From 10078e85a9dd67fb1b06ba2da31848b0856314f0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 03:54:39 -1100 Subject: [PATCH 01/20] +print --- src/cc/dice.cpp | 490 +++++++++++++++++++++++++++++++++++++-------- src/cc/rewards.cpp | 3 +- 2 files changed, 411 insertions(+), 82 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 159ac7a8c..55e7aa1b7 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -14,12 +14,86 @@ ******************************************************************************/ #include "CCdice.h" -#include "../txmempool.h" /* -*/ + in order to implement a dice game, we need a source of entropy, reasonably fast completion time and a way to manage the utxos. + + 1. CC vout locks "house" funds with hash(entropy) + half of shared secret + 2. bettor submits bet, with entropy, odds, houseid and sends combined amount into another CC vout. + 3. house account sends funds to winner with proof of entropy + 4. if timeout, bettor wins funds + + 2. and 3. can be done in mempool + */ -// start of consensus code +uint64_t DiceCalc(uint64_t amount,uint256 txid,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit) +{ + uint64_t duration,reward = 0; + if ( (duration= CCduration(txid)) < minseconds ) + { + return(0); + //duration = (uint32_t)time(NULL) - (1532713903 - 3600 * 24); + } else if ( duration > maxseconds ) + maxseconds = duration; + reward = (((amount * APR) / COIN) * duration) / (365*24*3600LL * 100); + fprintf(stderr,"amount %.8f %.8f %llu -> duration.%llu reward %.8f\n",(double)amount/COIN,((double)amount * APR)/COIN,(long long)((amount * APR) / (COIN * 365*24*3600)),(long long)duration,(double)reward/COIN); + return(reward); +} + +CScript EncodeDiceFundingOpRet(uint8_t funcid,uint64_t sbits,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit) +{ + CScript opret; uint8_t evalcode = EVAL_DICE; + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'F' << sbits << APR << minseconds << maxseconds << mindeposit); + return(opret); +} + +uint8_t DecodeDiceFundingOpRet(const CScript &scriptPubKey,uint64_t &sbits,uint64_t &APR,uint64_t &minseconds,uint64_t &maxseconds,uint64_t &mindeposit) +{ + std::vector vopret; uint8_t *script,e,f; + GetOpReturnData(scriptPubKey, vopret); + script = (uint8_t *)vopret.data(); + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> APR; ss >> minseconds; ss >> maxseconds; ss >> mindeposit) != 0 ) + { + if ( e == EVAL_DICE && f == 'F' ) + return(f); + } + return(0); +} + +CScript EncodeDiceOpRet(uint8_t funcid,uint64_t sbits,uint256 fundingtxid) +{ + CScript opret; uint8_t evalcode = EVAL_DICE; + opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << sbits << fundingtxid); + return(opret); +} + +uint8_t DecodeDiceOpRet(uint256 txid,const CScript &scriptPubKey,uint64_t &sbits,uint256 &fundingtxid) +{ + std::vector vopret; uint8_t *script,e,f,funcid; uint64_t APR,minseconds,maxseconds,mindeposit; + GetOpReturnData(scriptPubKey, vopret); + if ( vopret.size() > 2 ) + { + script = (uint8_t *)vopret.data(); + if ( script[0] == EVAL_DICE ) + { + if ( script[1] == 'F' ) + { + if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> APR; ss >> minseconds; ss >> maxseconds; ss >> mindeposit) != 0 ) + { + fundingtxid = txid; + return('F'); + } else fprintf(stderr,"unmarshal error for F\n"); + } + else if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> fundingtxid) != 0 ) + { + if ( e == EVAL_DICE && (f == 'L' || f == 'U' || f == 'A') ) + return(f); + else fprintf(stderr,"mismatched e.%02x f.(%c)\n",e,f); + } + } else fprintf(stderr,"script[0] %02x != EVAL_DICE\n",script[0]); + } else fprintf(stderr,"not enough opret.[%d]\n",(int32_t)vopret.size()); + return(0); +} uint64_t IsDicevout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) { @@ -32,23 +106,20 @@ uint64_t IsDicevout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) return(0); } -bool DiceExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) +bool DiceExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx,uint64_t txfee) { static uint256 zerohash; - CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; uint64_t inputs=0,outputs=0,assetoshis; + CTransaction vinTx; uint256 hashBlock; int32_t i,numvins,numvouts; uint64_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"); + return eval->Invalid("always should find vin, but didnt"); else { - //fprintf(stderr,"vini.%d check hash and vout\n",i); if ( hashBlock == zerohash ) return eval->Invalid("cant dice from mempool"); if ( (assetoshis= IsDicevout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) @@ -62,17 +133,17 @@ bool DiceExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction & if ( (assetoshis= IsDicevout(cp,tx,i)) != 0 ) outputs += assetoshis; } - if ( inputs != outputs+COIN+txfee ) + if ( inputs != outputs+txfee ) { fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs); - return eval->Invalid("mismatched inputs != outputs + COIN + txfee"); + return eval->Invalid("mismatched inputs != outputs + txfee"); } else return(true); } bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) { - int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; bool retval; + uint256 txid,fundingtxid,hashBlock; uint64_t sbits,APR,minseconds,maxseconds,mindeposit,amount,reward,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; uint8_t funcid; CScript scriptPubKey; CTransaction fundingTx,vinTx; numvins = tx.vin.size(); numvouts = tx.vout.size(); preventCCvins = preventCCvouts = -1; @@ -80,104 +151,361 @@ bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) return eval->Invalid("no vouts"); else { - //fprintf(stderr,"check vins\n"); - for (i=0; iGetTxUnconfirmed(fundingtxid,fundingTx,hashBlock) == 0 ) + return eval->Invalid("cant find fundingtxid"); + else if ( fundingTx.vout.size() > 0 && DecodeDiceFundingOpRet(fundingTx.vout[fundingTx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) != 'F' ) + return eval->Invalid("fundingTx not valid"); + switch ( funcid ) { - fprintf(stderr,"diceget invalid vini\n"); - return eval->Invalid("illegal normal vini"); + case 'F': + //vins.*: normal inputs + //vout.0: CC vout for funding + //vout.1: normal marker vout for easy searching + //vout.2: normal change + //vout.n-1: opreturn 'F' sbits APR minseconds maxseconds mindeposit + return eval->Invalid("unexpected DiceValidate for createfunding"); + break; + case 'A': + //vins.*: normal inputs + //vout.0: CC vout for funding + //vout.1: normal change + //vout.n-1: opreturn 'A' sbits fundingtxid + return eval->Invalid("unexpected DiceValidate for addfunding"); + break; + case 'L': + //vins.*: normal inputs + //vout.0: CC vout for locked funds + //vout.1: normal output to unlock address + //vout.2: change + //vout.n-1: opreturn 'L' sbits fundingtxid + return eval->Invalid("unexpected DiceValidate for lock"); + break; + case 'U': + //vin.0: locked funds CC vout.0 from lock + //vin.1+: funding CC vout.0 from 'F' and 'A' and 'U' + //vout.0: funding CC change + //vout.1: normal output to unlock address + //vout.n-1: opreturn 'U' sbits fundingtxid + for (i=0; iismyvin)(tx.vin[i].scriptSig) == 0 ) + return eval->Invalid("unexpected normal vin for unlock"); + } + if ( DiceExactAmounts(cp,eval,tx,txfee+tx.vout[1].nValue) == 0 ) + return false; + else if ( eval->GetTxUnconfirmed(tx.vin[0].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("always should find vin.0, but didnt"); + else if ( vinTx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 ) + return eval->Invalid("lock tx vout.0 is normal output"); + else if ( tx.vout.size() < 3 ) + return eval->Invalid("unlock tx not enough vouts"); + else if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 ) + return eval->Invalid("unlock tx vout.0 is normal output"); + else if ( tx.vout[1].scriptPubKey.IsPayToCryptoCondition() != 0 ) + return eval->Invalid("unlock tx vout.1 is CC output"); + else if ( tx.vout[1].scriptPubKey != vinTx.vout[1].scriptPubKey ) + return eval->Invalid("unlock tx vout.1 mismatched scriptPubKey"); + amount = vinTx.vout[0].nValue; + reward = DiceCalc(amount,tx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit); + if ( tx.vout[1].nValue > amount+reward ) + return eval->Invalid("unlock tx vout.1 isnt amount+reward"); + preventCCvouts = 1; + break; } } - //fprintf(stderr,"check amounts\n"); - if ( DiceExactAmounts(cp,eval,tx,1,10000) == false ) - { - fprintf(stderr,"diceget invalid amount\n"); - return false; - } - else - { - preventCCvouts = 1; - if ( IsDicevout(cp,tx,0) != 0 ) - { - preventCCvouts++; - i = 1; - } else i = 0; - if ( tx.vout[i].nValue != COIN ) - return eval->Invalid("invalid dice output"); - retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); - if ( retval != 0 ) - fprintf(stderr,"diceget validated\n"); - else fprintf(stderr,"diceget invalid\n"); - return(retval); - } + return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts)); } + return(true); } -// end of consensus code -// helper functions for rpc calls in rpcwallet.cpp - -uint64_t AddDiceInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs) +// 'L' vs 'F' and 'A' +uint64_t AddDiceInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs) { - char coinaddr[64]; uint64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t n = 0; + char coinaddr[64],str[65]; uint64_t sbits,APR,minseconds,maxseconds,mindeposit,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t j,vout,n = 0; uint8_t funcid; std::vector > unspentOutputs; GetCCaddress(cp,coinaddr,pk); SetCCunspents(unspentOutputs,coinaddr); for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) { txid = it->first.txhash; - // prevent dup - if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) + vout = (int32_t)it->first.index; + fprintf(stderr,"(%s) %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + for (j=0; j 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 ) { - if ( (nValue= IsDicevout(cp,vintx,(int32_t)it->first.index)) > 0 ) + if ( (funcid= DecodeDiceOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) != 0 ) { + fprintf(stderr,"fundsflag.%d (%c) %.8f %.8f\n",fundsflag,funcid,(double)tx.vout[vout].nValue/COIN,(double)it->second.satoshis/COIN); + if ( fundsflag != 0 && funcid != 'F' && funcid != 'A' && funcid != 'U' ) + continue; + else if ( fundsflag == 0 && (funcid != 'L' || tx.vout.size() < 4) ) + continue; if ( total != 0 && maxinputs != 0 ) - mtx.vin.push_back(CTxIn(txid,(int32_t)it->first.index,CScript())); - nValue = it->second.satoshis; - totalinputs += nValue; + { + if ( fundsflag == 0 ) + scriptPubKey = tx.vout[1].scriptPubKey; + mtx.vin.push_back(CTxIn(txid,vout,CScript())); + } + totalinputs += it->second.satoshis; n++; if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) break; - } + } else fprintf(stderr,"null funcid\n"); } } return(totalinputs); } -std::string DiceBet(uint64_t txfee,uint64_t amount,uint64_t odds) +uint64_t DicePlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,uint256 reffundingtxid) { - CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_DICE); - if ( txfee == 0 ) - txfee = 10000; - dicepk = GetUnspendable(cp,0); - mypk = pubkey2pk(Mypubkey()); - if ( (inputs= AddDiceInputs(cp,mtx,dicepk,nValue+txfee,60)) > 0 ) + char coinaddr[64]; uint64_t sbits,APR,minseconds,maxseconds,mindeposit,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid; + std::vector > unspentOutputs; + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) { - if ( inputs > nValue ) - CCchange = (inputs - nValue - txfee); - if ( CCchange != 0 ) - mtx.vout.push_back(MakeCC1vout(EVAL_DICE,CCchange,dicepk)); - mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret)); - } else fprintf(stderr,"cant find dice inputs\n"); - return(0); -} - -std::string DiceFund(uint64_t txfee,uint64_t funds) -{ - CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; struct CCcontract_info *cp,C; - cp = CCinit(&C,EVAL_DICE); - if ( txfee == 0 ) - txfee = 10000; - mypk = pubkey2pk(Mypubkey()); - dicepk = GetUnspendable(cp,0); - if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 ) - { - mtx.vout.push_back(MakeCC1vout(EVAL_DICE,funds,dicepk)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); + txid = it->first.txhash; + vout = (int32_t)it->first.index; + if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 ) + { + if ( (funcid= DecodeDiceOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) != 0 ) + { + if ( (funcid == 'F' && reffundingtxid == txid) || reffundingtxid == fundingtxid ) + { + if ( refsbits == sbits && (nValue= IsDicevout(cp,tx,vout)) > 0 ) + totalinputs += nValue; + else fprintf(stderr,"refsbits.%llx sbits.%llx nValue %.8f\n",(long long)refsbits,(long long)sbits,(double)nValue/COIN); + } else fprintf(stderr,"else case\n"); + } else fprintf(stderr,"funcid.%d %c skipped %.8f\n",funcid,funcid,(double)tx.vout[vout].nValue/COIN); + } } + return(totalinputs); +} + +bool DicePlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey dicepk,uint64_t &APR,uint64_t &minseconds,uint64_t &maxseconds,uint64_t &mindeposit) +{ + char CCaddr[64]; uint64_t sbits; uint256 txid,hashBlock; CTransaction tx; + std::vector > txids; + GetCCaddress(cp,CCaddr,dicepk); + SetCCtxids(txids,CCaddr); + for (std::vector >::const_iterator it=txids.begin(); it!=txids.end(); it++) + { + //int height = it->first.blockHeight; + txid = it->first.txhash; + if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && ConstrainVout(tx.vout[0],1,CCaddr,0) != 0 ) + { + if ( DecodeDiceFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 'F' ) + { + if ( sbits == refsbits ) + return(true); + } + } + } + return(false); +} + +UniValue DiceInfo(uint256 diceid) +{ + UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction vintx; uint64_t APR,minseconds,maxseconds,mindeposit,sbits; char str[67],numstr[65]; + if ( GetTransaction(diceid,vintx,hashBlock,false) == 0 ) + { + fprintf(stderr,"cant find fundingtxid\n"); + result.push_back(Pair("error","cant find fundingtxid")); + return(result); + } + if ( vintx.vout.size() > 0 && DecodeDiceFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 0 ) + { + fprintf(stderr,"fundingtxid isnt dice creation txid\n"); + result.push_back(Pair("error","fundingtxid isnt dice creation txid")); + return(result); + } + result.push_back(Pair("result","success")); + result.push_back(Pair("fundingtxid",uint256_str(str,diceid))); + unstringbits(str,sbits); + result.push_back(Pair("name",str)); + result.push_back(Pair("sbits",sbits)); + sprintf(numstr,"%.8f",(double)APR/COIN); + result.push_back(Pair("APR",numstr)); + result.push_back(Pair("minseconds",minseconds)); + result.push_back(Pair("maxseconds",maxseconds)); + sprintf(numstr,"%.8f",(double)mindeposit/COIN); + result.push_back(Pair("mindeposit",numstr)); + sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue/COIN); + result.push_back(Pair("funding",numstr)); + return(result); +} + +UniValue DiceList() +{ + UniValue result(UniValue::VARR); std::vector > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock; CTransaction vintx; uint64_t sbits,APR,minseconds,maxseconds,mindeposit; char str[65]; + cp = CCinit(&C,EVAL_DICE); + 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 && DecodeDiceFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) != 0 ) + { + result.push_back(uint256_str(str,txid)); + } + } + } + return(result); +} + +std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t APR,int64_t minseconds,int64_t maxseconds,int64_t mindeposit) +{ + CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C; + if ( funds < 0 || mindeposit < 0 || minseconds < 0 || maxseconds < 0 ) + { + fprintf(stderr,"negative parameter error\n"); + return(0); + } + cp = CCinit(&C,EVAL_DICE); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + dicepk = GetUnspendable(cp,0); + sbits = stringbits(planstr); + if ( DicePlanExists(cp,sbits,dicepk,a,b,c,d) != 0 ) + { + fprintf(stderr,"Dice plan (%s) already exists\n",planstr); + return(0); + } + if ( AddNormalinputs(mtx,mypk,funds+2*txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,dicepk)); + mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(dicepk)) << OP_CHECKSIG)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceFundingOpRet('F',sbits,APR,minseconds,maxseconds,mindeposit))); + } + fprintf(stderr,"cant find enough inputs\n"); return(0); } +std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount) +{ + CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C; + if ( amount < 0 ) + { + fprintf(stderr,"negative parameter error\n"); + return(0); + } + cp = CCinit(&C,EVAL_DICE); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + dicepk = GetUnspendable(cp,0); + sbits = stringbits(planstr); + if ( DicePlanExists(cp,sbits,dicepk,a,b,c,d) == 0 ) + { + fprintf(stderr,"Dice plan %s doesnt exist\n",planstr); + return(0); + } + sbits = stringbits(planstr); + if ( AddNormalinputs(mtx,mypk,amount+txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,dicepk)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceOpRet('A',sbits,fundingtxid))); + } else fprintf(stderr,"cant find enough inputs\n"); + fprintf(stderr,"cant find fundingtxid\n"); + return(0); +} + +std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t wager,int32_t odds) +{ + CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits,funding,APR,minseconds,maxseconds,minwager; struct CCcontract_info *cp,C; + if ( wager < 0 ) + { + fprintf(stderr,"negative parameter error\n"); + return(0); + } + cp = CCinit(&C,EVAL_DICE); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + dicepk = GetUnspendable(cp,0); + sbits = stringbits(planstr); + if ( DicePlanExists(cp,sbits,dicepk,APR,minseconds,maxseconds,minwager) == 0 ) + { + fprintf(stderr,"Dice plan %s doesnt exist\n",planstr); + return(0); + } + if ( wager < minwager ) + { + fprintf(stderr,"Dice plan %s wager %.8f < minwager %.8f\n",planstr,(double)wager/COIN,(double)minwager/COIN); + return(0); + } + if ( (funding= DicePlanFunds(sbits,cp,dicepk,fundingtxid)) >= wager ) // arbitrary cmpval + { + if ( AddNormalinputs(mtx,mypk,wager+2*txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(cp->evalcode,wager,dicepk)); + mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceOpRet('L',sbits,fundingtxid))); + } else fprintf(stderr,"cant find enough inputs %.8f note enough for %.8f\n",(double)funding/COIN,(double)wager/COIN); + } + fprintf(stderr,"cant find dice inputs\n"); + return(0); +} + +std::string DiceUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid) +{ + CMutableTransaction mtx; CTransaction tx; char coinaddr[64]; CPubKey mypk,dicepk; CScript opret,scriptPubKey,ignore; uint256 hashBlock; uint64_t funding,sbits,reward=0,amount=0,inputs,CCchange=0,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_DICE); + if ( txfee == 0 ) + txfee = 10000; + dicepk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + sbits = stringbits(planstr); + if ( DicePlanExists(cp,sbits,dicepk,APR,minseconds,maxseconds,mindeposit) == 0 ) + { + fprintf(stderr,"Dice plan %s doesnt exist\n",planstr); + return(0); + } + // need to deal with finding the right utxos + if ( locktxid == zeroid ) + amount = AddDiceInputs(scriptPubKey,0,cp,mtx,dicepk,(1LL << 30),1); + else + { + GetCCaddress(cp,coinaddr,dicepk); + if ( (amount= CCutxovalue(coinaddr,locktxid,0)) == 0 ) + { + fprintf(stderr,"%s locktxid/v0 is spent\n",coinaddr); + return(0); + } + if ( GetTransaction(locktxid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 ) + { + scriptPubKey = tx.vout[1].scriptPubKey; + mtx.vin.push_back(CTxIn(locktxid,0,CScript())); + } + else + { + fprintf(stderr,"%s no normal vout.1 in locktxid\n",coinaddr); + return(0); + } + } + if ( amount > 0 && (reward= DiceCalc(amount,mtx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit)) > txfee && scriptPubKey.size() > 0 ) + { + if ( (inputs= AddDiceInputs(ignore,1,cp,mtx,dicepk,reward+txfee,30)) > 0 ) + { + if ( inputs >= (reward + 2*txfee) ) + CCchange = (inputs - (reward + txfee)); + fprintf(stderr,"inputs %.8f CCchange %.8f amount %.8f reward %.8f\n",(double)inputs/COIN,(double)CCchange/COIN,(double)amount/COIN,(double)reward/COIN); + mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,dicepk)); + mtx.vout.push_back(CTxOut(amount+reward,scriptPubKey)); + return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,EncodeDiceOpRet('U',sbits,fundingtxid))); + } + fprintf(stderr,"cant find enough dice inputs\n"); + } + fprintf(stderr,"amount %.8f -> reward %.8f\n",(double)amount/COIN,(double)reward/COIN); + return(0); +} diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index 2944c1bee..b4fcf737e 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -69,12 +69,13 @@ uint64_t RewardsCalc(uint64_t amount,uint256 txid,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit) { uint64_t duration,reward = 0; + fprintf(stderr,"minseconds %llu maxseconds %llu\n",(long long)minseconds,(long long)maxseconds); if ( (duration= CCduration(txid)) < minseconds ) { return(0); //duration = (uint32_t)time(NULL) - (1532713903 - 3600 * 24); } else if ( duration > maxseconds ) - maxseconds = duration; + duration = maxseconds; reward = (((amount * APR) / COIN) * duration) / (365*24*3600LL * 100); fprintf(stderr,"amount %.8f %.8f %llu -> duration.%llu reward %.8f\n",(double)amount/COIN,((double)amount * APR)/COIN,(long long)((amount * APR) / (COIN * 365*24*3600)),(long long)duration,(double)reward/COIN); return(reward); From 0cec24398f31378166b122e3953f0efc3070d781 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 03:56:08 -1100 Subject: [PATCH 02/20] Test --- src/wallet/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index ae9c9b784..96d23447d 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5095,7 +5095,7 @@ UniValue dicefund(const UniValue& params, bool fHelp) 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"); funds = atof(params[0].get_str().c_str()) * COIN; - hex = DiceFund(0,funds); + //hex = DiceFund(0,funds); if ( hex.size() > 0 ) { result.push_back(Pair("result", "success")); @@ -5115,7 +5115,7 @@ UniValue dicebet(const UniValue& params, bool fHelp) if ( params.size() == 2 ) odds = atof(params[1].get_str().c_str()) * COIN; else odds = 1; - hex = DiceBet(0,amount,odds); + //hex = DiceBet(0,amount,odds); if ( hex.size() > 0 ) { result.push_back(Pair("result", "success")); From 42106faf1884a7e5d67f90747ef779ab7f3325cb Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 04:05:14 -1100 Subject: [PATCH 03/20] Test --- src/wallet/rpcwallet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 96d23447d..f7136f43c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4972,6 +4972,7 @@ UniValue rewardscreatefunding(const UniValue& params, bool fHelp) mindeposit = 100 * COIN; name = (char *)params[0].get_str().c_str(); funds = atof(params[1].get_str().c_str()) * COIN; + fprintf(stderr,"params.size() %d\n",(int32_t)params.size()); if ( params.size() > 2 ) { APR = atof(params[2].get_str().c_str()) * COIN; From 733a1c4c3049d1ed911a3601688a4bccc6e8b9c3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 04:11:25 -1100 Subject: [PATCH 04/20] Test --- src/rpcclient.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 9d1d0b336..a89e538dd 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -148,6 +148,9 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getproofroot", 2}, { "height_MoM", 1}, { "calc_MoM", 2}, + { "rewardscreatefunding", 3}, + { "rewardscreatefunding", 4}, + { "rewardscreatefunding", 5}, }; class CRPCConvertTable From 05eccd86e61c7ab6e0aefbf5a22385f3768043bb Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 04:14:19 -1100 Subject: [PATCH 05/20] Test --- src/rpcclient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index a89e538dd..18a8782b9 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -195,7 +195,7 @@ UniValue ParseNonRFCJSONValue(const std::string& strVal) UniValue RPCConvertValues(const std::string &strMethod, const std::vector &strParams) { UniValue params(UniValue::VARR); - + fprintf(stderr,"strParams.size() %d\n",(int32_t)strParams.size()); for (unsigned int idx = 0; idx < strParams.size(); idx++) { const std::string& strVal = strParams[idx]; From f4e21be41c2118945916d647803e5847df5049ad Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 04:16:26 -1100 Subject: [PATCH 06/20] Fix c script --- src/rpcclient.cpp | 5 +---- src/wallet/rpcwallet.cpp | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 18a8782b9..9d1d0b336 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -148,9 +148,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getproofroot", 2}, { "height_MoM", 1}, { "calc_MoM", 2}, - { "rewardscreatefunding", 3}, - { "rewardscreatefunding", 4}, - { "rewardscreatefunding", 5}, }; class CRPCConvertTable @@ -195,7 +192,7 @@ UniValue ParseNonRFCJSONValue(const std::string& strVal) UniValue RPCConvertValues(const std::string &strMethod, const std::vector &strParams) { UniValue params(UniValue::VARR); - fprintf(stderr,"strParams.size() %d\n",(int32_t)strParams.size()); + for (unsigned int idx = 0; idx < strParams.size(); idx++) { const std::string& strVal = strParams[idx]; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f7136f43c..96d23447d 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4972,7 +4972,6 @@ UniValue rewardscreatefunding(const UniValue& params, bool fHelp) mindeposit = 100 * COIN; name = (char *)params[0].get_str().c_str(); funds = atof(params[1].get_str().c_str()) * COIN; - fprintf(stderr,"params.size() %d\n",(int32_t)params.size()); if ( params.size() > 2 ) { APR = atof(params[2].get_str().c_str()) * COIN; From ba30129fa6d93c71c93a4a065adfc485a85e1fcb Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 04:27:59 -1100 Subject: [PATCH 07/20] Test --- src/cc/rewards.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index b4fcf737e..1d7c454a2 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -323,7 +323,7 @@ uint64_t RewardsPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey p if ( refsbits == sbits && (nValue= IsRewardsvout(cp,tx,vout)) > 0 ) totalinputs += nValue; else fprintf(stderr,"refsbits.%llx sbits.%llx nValue %.8f\n",(long long)refsbits,(long long)sbits,(double)nValue/COIN); - } else fprintf(stderr,"else case\n"); + } //else fprintf(stderr,"else case\n"); } else fprintf(stderr,"funcid.%d %c skipped %.8f\n",funcid,funcid,(double)tx.vout[vout].nValue/COIN); } } @@ -342,6 +342,7 @@ bool RewardsPlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey rewa txid = it->first.txhash; if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && ConstrainVout(tx.vout[0],1,CCaddr,0) != 0 ) { + char str[65]; fprintf(stderr,"rewards plan %s\n",uint256_str(str,txid)); if ( DecodeRewardsFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 'F' ) { if ( sbits == refsbits ) @@ -511,7 +512,7 @@ std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint2 fprintf(stderr,"Rewards plan %s doesnt exist\n",planstr); return(0); } - // need to deal with finding the right utxos + fprintf(stderr,"APR %.8f minseconds.%llu maxseconds.%llu mindeposit %.8f\n",(double)APR/COIN,(long long)minseconds,(long long)maxseconds,(double)mindeposit/COIN); if ( locktxid == zeroid ) amount = AddRewardsInputs(scriptPubKey,0,cp,mtx,rewardspk,(1LL << 30),1); else From d0d96ab044de07ab8b858d431ce336e2be28427f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 05:06:39 -1100 Subject: [PATCH 08/20] Initial dice morph from rewards.cpp --- src/cc/CCdice.h | 2 +- src/cc/dice.cpp | 83 ++++++++++++++++++++-------------------- src/cc/rewards.cpp | 6 +-- src/wallet/rpcwallet.cpp | 14 ++++--- 4 files changed, 55 insertions(+), 50 deletions(-) diff --git a/src/cc/CCdice.h b/src/cc/CCdice.h index 7c89d18d5..d7666032f 100644 --- a/src/cc/CCdice.h +++ b/src/cc/CCdice.h @@ -24,6 +24,6 @@ bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); std::string DiceFund(uint64_t txfee,uint64_t funds); -std::string DiceBet(uint64_t txfee,uint64_t amount,uint64_t odds); +std::string DiceCreateFunding(uint64_t txfee,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks); #endif diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 55e7aa1b7..75ab8721b 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -26,9 +26,9 @@ 2. and 3. can be done in mempool */ -uint64_t DiceCalc(uint64_t amount,uint256 txid,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit) +uint64_t DiceCalc(uint64_t amount,uint256 txid,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks) { - uint64_t duration,reward = 0; + /*uint64_t duration,reward = 0; if ( (duration= CCduration(txid)) < minseconds ) { return(0); @@ -37,22 +37,23 @@ uint64_t DiceCalc(uint64_t amount,uint256 txid,uint64_t APR,uint64_t minseconds, maxseconds = duration; reward = (((amount * APR) / COIN) * duration) / (365*24*3600LL * 100); fprintf(stderr,"amount %.8f %.8f %llu -> duration.%llu reward %.8f\n",(double)amount/COIN,((double)amount * APR)/COIN,(long long)((amount * APR) / (COIN * 365*24*3600)),(long long)duration,(double)reward/COIN); - return(reward); + return(reward);*/ + return(0); } -CScript EncodeDiceFundingOpRet(uint8_t funcid,uint64_t sbits,uint64_t APR,uint64_t minseconds,uint64_t maxseconds,uint64_t mindeposit) +CScript EncodeDiceFundingOpRet(uint8_t funcid,uint64_t sbits,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks) { CScript opret; uint8_t evalcode = EVAL_DICE; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'F' << sbits << APR << minseconds << maxseconds << mindeposit); + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'F' << sbits << minbet << maxbet << maxodds << forfeitblocks); return(opret); } -uint8_t DecodeDiceFundingOpRet(const CScript &scriptPubKey,uint64_t &sbits,uint64_t &APR,uint64_t &minseconds,uint64_t &maxseconds,uint64_t &mindeposit) +uint8_t DecodeDiceFundingOpRet(const CScript &scriptPubKey,uint64_t &sbits,int64_t &minbet,int64_t &maxbet,int64_t &maxodds,int64_t &forfeitblocks) { std::vector vopret; uint8_t *script,e,f; GetOpReturnData(scriptPubKey, vopret); script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> APR; ss >> minseconds; ss >> maxseconds; ss >> mindeposit) != 0 ) + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> minbet; ss >> maxbet; ss >> maxodds; ss >> forfeitblocks) != 0 ) { if ( e == EVAL_DICE && f == 'F' ) return(f); @@ -69,7 +70,7 @@ CScript EncodeDiceOpRet(uint8_t funcid,uint64_t sbits,uint256 fundingtxid) uint8_t DecodeDiceOpRet(uint256 txid,const CScript &scriptPubKey,uint64_t &sbits,uint256 &fundingtxid) { - std::vector vopret; uint8_t *script,e,f,funcid; uint64_t APR,minseconds,maxseconds,mindeposit; + std::vector vopret; uint8_t *script,e,f,funcid; int64_t minbet,maxbet,maxodds,forfeitblocks; GetOpReturnData(scriptPubKey, vopret); if ( vopret.size() > 2 ) { @@ -78,7 +79,7 @@ uint8_t DecodeDiceOpRet(uint256 txid,const CScript &scriptPubKey,uint64_t &sbits { if ( script[1] == 'F' ) { - if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> APR; ss >> minseconds; ss >> maxseconds; ss >> mindeposit) != 0 ) + if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> sbits; ss >> minbet; ss >> maxbet; ss >> maxodds; ss >> forfeitblocks) != 0 ) { fundingtxid = txid; return('F'); @@ -143,7 +144,7 @@ bool DiceExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransaction & bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) { - uint256 txid,fundingtxid,hashBlock; uint64_t sbits,APR,minseconds,maxseconds,mindeposit,amount,reward,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; uint8_t funcid; CScript scriptPubKey; CTransaction fundingTx,vinTx; + uint256 txid,fundingtxid,hashBlock; uint64_t sbits,minbet,maxbet,maxodds,forfeitblocks,amount,reward,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; uint8_t funcid; CScript scriptPubKey; CTransaction fundingTx,vinTx; numvins = tx.vin.size(); numvouts = tx.vout.size(); preventCCvins = preventCCvouts = -1; @@ -156,7 +157,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) { if ( eval->GetTxUnconfirmed(fundingtxid,fundingTx,hashBlock) == 0 ) return eval->Invalid("cant find fundingtxid"); - else if ( fundingTx.vout.size() > 0 && DecodeDiceFundingOpRet(fundingTx.vout[fundingTx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) != 'F' ) + else if ( fundingTx.vout.size() > 0 && DecodeDiceFundingOpRet(fundingTx.vout[fundingTx.vout.size()-1].scriptPubKey,sbits,minbet,maxbet,maxodds,forfeitblocks) != 'F' ) return eval->Invalid("fundingTx not valid"); switch ( funcid ) { @@ -209,7 +210,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) else if ( tx.vout[1].scriptPubKey != vinTx.vout[1].scriptPubKey ) return eval->Invalid("unlock tx vout.1 mismatched scriptPubKey"); amount = vinTx.vout[0].nValue; - reward = DiceCalc(amount,tx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit); + reward = DiceCalc(amount,tx.vin[0].prevout.hash,minbet,maxbet,maxodds,forfeitblocks); if ( tx.vout[1].nValue > amount+reward ) return eval->Invalid("unlock tx vout.1 isnt amount+reward"); preventCCvouts = 1; @@ -224,7 +225,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) // 'L' vs 'F' and 'A' uint64_t AddDiceInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs) { - char coinaddr[64],str[65]; uint64_t sbits,APR,minseconds,maxseconds,mindeposit,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t j,vout,n = 0; uint8_t funcid; + char coinaddr[64],str[65]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t j,vout,n = 0; uint8_t funcid; std::vector > unspentOutputs; GetCCaddress(cp,coinaddr,pk); SetCCunspents(unspentOutputs,coinaddr); @@ -265,7 +266,7 @@ uint64_t AddDiceInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontract uint64_t DicePlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,uint256 reffundingtxid) { - char coinaddr[64]; uint64_t sbits,APR,minseconds,maxseconds,mindeposit,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid; + char coinaddr[64]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid; std::vector > unspentOutputs; GetCCaddress(cp,coinaddr,pk); SetCCunspents(unspentOutputs,coinaddr); @@ -282,14 +283,14 @@ uint64_t DicePlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,u if ( refsbits == sbits && (nValue= IsDicevout(cp,tx,vout)) > 0 ) totalinputs += nValue; else fprintf(stderr,"refsbits.%llx sbits.%llx nValue %.8f\n",(long long)refsbits,(long long)sbits,(double)nValue/COIN); - } else fprintf(stderr,"else case\n"); + } //else fprintf(stderr,"else case\n"); } else fprintf(stderr,"funcid.%d %c skipped %.8f\n",funcid,funcid,(double)tx.vout[vout].nValue/COIN); } } return(totalinputs); } -bool DicePlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey dicepk,uint64_t &APR,uint64_t &minseconds,uint64_t &maxseconds,uint64_t &mindeposit) +bool DicePlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey dicepk,int64_t &minbet,int64_t &maxbet,int64_t &maxodds,int64_t &forfeitblocks) { char CCaddr[64]; uint64_t sbits; uint256 txid,hashBlock; CTransaction tx; std::vector > txids; @@ -301,7 +302,7 @@ bool DicePlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey dicepk, txid = it->first.txhash; if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && ConstrainVout(tx.vout[0],1,CCaddr,0) != 0 ) { - if ( DecodeDiceFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 'F' ) + if ( DecodeDiceFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,sbits,minbet,maxbet,maxodds,forfeitblocks) == 'F' ) { if ( sbits == refsbits ) return(true); @@ -313,14 +314,14 @@ bool DicePlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey dicepk, UniValue DiceInfo(uint256 diceid) { - UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction vintx; uint64_t APR,minseconds,maxseconds,mindeposit,sbits; char str[67],numstr[65]; + UniValue result(UniValue::VOBJ); uint256 hashBlock; CTransaction vintx; int64_t minbet,maxbet,maxodds,forfeitblocks; uint64_t sbits; char str[67],numstr[65]; if ( GetTransaction(diceid,vintx,hashBlock,false) == 0 ) { fprintf(stderr,"cant find fundingtxid\n"); result.push_back(Pair("error","cant find fundingtxid")); return(result); } - if ( vintx.vout.size() > 0 && DecodeDiceFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 0 ) + if ( vintx.vout.size() > 0 && DecodeDiceFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,minbet,maxbet,maxodds,forfeitblocks) == 0 ) { fprintf(stderr,"fundingtxid isnt dice creation txid\n"); result.push_back(Pair("error","fundingtxid isnt dice creation txid")); @@ -331,12 +332,12 @@ UniValue DiceInfo(uint256 diceid) unstringbits(str,sbits); result.push_back(Pair("name",str)); result.push_back(Pair("sbits",sbits)); - sprintf(numstr,"%.8f",(double)APR/COIN); - result.push_back(Pair("APR",numstr)); - result.push_back(Pair("minseconds",minseconds)); - result.push_back(Pair("maxseconds",maxseconds)); - sprintf(numstr,"%.8f",(double)mindeposit/COIN); - result.push_back(Pair("mindeposit",numstr)); + 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)); + result.push_back(Pair("forfeitblocks",forfeitblocks)); sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue/COIN); result.push_back(Pair("funding",numstr)); return(result); @@ -344,7 +345,7 @@ UniValue DiceInfo(uint256 diceid) UniValue DiceList() { - UniValue result(UniValue::VARR); std::vector > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock; CTransaction vintx; uint64_t sbits,APR,minseconds,maxseconds,mindeposit; char str[65]; + UniValue result(UniValue::VARR); std::vector > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock; CTransaction vintx; uint64_t sbits; int64_t minbet,maxbet,maxodds,forfeitblocks; char str[65]; cp = CCinit(&C,EVAL_DICE); SetCCtxids(addressIndex,cp->normaladdr); for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) @@ -352,7 +353,7 @@ UniValue DiceList() txid = it->first.txhash; if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) { - if ( vintx.vout.size() > 0 && DecodeDiceFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) != 0 ) + if ( vintx.vout.size() > 0 && DecodeDiceFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,minbet,maxbet,maxodds,forfeitblocks) != 0 ) { result.push_back(uint256_str(str,txid)); } @@ -361,10 +362,10 @@ UniValue DiceList() return(result); } -std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t APR,int64_t minseconds,int64_t maxseconds,int64_t mindeposit) +std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks) { - CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C; - if ( funds < 0 || mindeposit < 0 || minseconds < 0 || maxseconds < 0 ) + CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits; int64_t a,b,c,d; struct CCcontract_info *cp,C; + if ( funds < 0 || minbet < 0 || maxbet < 0 || maxodds < 1 || forfeitblocks < 0 || forefeitblocks > 1440 ) { fprintf(stderr,"negative parameter error\n"); return(0); @@ -384,7 +385,7 @@ std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t { mtx.vout.push_back(MakeCC1vout(cp->evalcode,funds,dicepk)); mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(dicepk)) << OP_CHECKSIG)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceFundingOpRet('F',sbits,APR,minseconds,maxseconds,mindeposit))); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceFundingOpRet('F',sbits,minbet,maxbet,maxodds,forfeitblocks))); } fprintf(stderr,"cant find enough inputs\n"); return(0); @@ -392,7 +393,7 @@ std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount) { - CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C; + CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits; int64_t a,b,c,d; struct CCcontract_info *cp,C; if ( amount < 0 ) { fprintf(stderr,"negative parameter error\n"); @@ -419,9 +420,9 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6 return(0); } -std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t wager,int32_t odds) +std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds) { - CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits,funding,APR,minseconds,maxseconds,minwager; struct CCcontract_info *cp,C; + CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits; int64_t funding,minbet,maxbet,maxodds,forfeitblocks; struct CCcontract_info *cp,C; if ( wager < 0 ) { fprintf(stderr,"negative parameter error\n"); @@ -433,17 +434,17 @@ std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t wag mypk = pubkey2pk(Mypubkey()); dicepk = GetUnspendable(cp,0); sbits = stringbits(planstr); - if ( DicePlanExists(cp,sbits,dicepk,APR,minseconds,maxseconds,minwager) == 0 ) + if ( DicePlanExists(cp,sbits,dicepk,minbet,maxbet,maxodds,forfeitblocks) == 0 ) { fprintf(stderr,"Dice plan %s doesnt exist\n",planstr); return(0); } - if ( wager < minwager ) + if ( bet < minbet ) { - fprintf(stderr,"Dice plan %s wager %.8f < minwager %.8f\n",planstr,(double)wager/COIN,(double)minwager/COIN); + fprintf(stderr,"Dice plan %s bet %.8f < minbet %.8f\n",planstr,(double)bet/COIN,(double)minbet/COIN); return(0); } - if ( (funding= DicePlanFunds(sbits,cp,dicepk,fundingtxid)) >= wager ) // arbitrary cmpval + if ( (funding= DicePlanFunds(sbits,cp,dicepk,fundingtxid)) >= bet*odds+txfee ) { if ( AddNormalinputs(mtx,mypk,wager+2*txfee,64) > 0 ) { @@ -458,14 +459,14 @@ std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t wag std::string DiceUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid) { - CMutableTransaction mtx; CTransaction tx; char coinaddr[64]; CPubKey mypk,dicepk; CScript opret,scriptPubKey,ignore; uint256 hashBlock; uint64_t funding,sbits,reward=0,amount=0,inputs,CCchange=0,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C; + CMutableTransaction mtx; CTransaction tx; char coinaddr[64]; CPubKey mypk,dicepk; CScript opret,scriptPubKey,ignore; uint256 hashBlock; uint64_t funding,sbits,reward=0,amount=0,inputs,CCchange=0; int64_t minbet,maxbet,maxodds,forfeitblocks; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_DICE); if ( txfee == 0 ) txfee = 10000; dicepk = GetUnspendable(cp,0); mypk = pubkey2pk(Mypubkey()); sbits = stringbits(planstr); - if ( DicePlanExists(cp,sbits,dicepk,APR,minseconds,maxseconds,mindeposit) == 0 ) + if ( DicePlanExists(cp,sbits,dicepk,minbet,maxbet,maxodds,forfeitblocks) == 0 ) { fprintf(stderr,"Dice plan %s doesnt exist\n",planstr); return(0); @@ -492,7 +493,7 @@ std::string DiceUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 return(0); } } - if ( amount > 0 && (reward= DiceCalc(amount,mtx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit)) > txfee && scriptPubKey.size() > 0 ) + if ( amount > 0 && (reward= DiceCalc(amount,mtx.vin[0].prevout.hash,minbet,maxbet,maxodds,forfeitblocks)) > txfee && scriptPubKey.size() > 0 ) { if ( (inputs= AddDiceInputs(ignore,1,cp,mtx,dicepk,reward+txfee,30)) > 0 ) { diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index 1d7c454a2..ba7cd5657 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -265,7 +265,7 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t // 'L' vs 'F' and 'A' uint64_t AddRewardsInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint64_t total,int32_t maxinputs) { - char coinaddr[64],str[65]; uint64_t sbits,APR,minseconds,maxseconds,mindeposit,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t j,vout,n = 0; uint8_t funcid; + char coinaddr[64],str[65]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t j,vout,n = 0; uint8_t funcid; std::vector > unspentOutputs; GetCCaddress(cp,coinaddr,pk); SetCCunspents(unspentOutputs,coinaddr); @@ -306,7 +306,7 @@ uint64_t AddRewardsInputs(CScript &scriptPubKey,int32_t fundsflag,struct CCcontr uint64_t RewardsPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,uint256 reffundingtxid) { - char coinaddr[64]; uint64_t sbits,APR,minseconds,maxseconds,mindeposit,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid; + char coinaddr[64]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid; std::vector > unspentOutputs; GetCCaddress(cp,coinaddr,pk); SetCCunspents(unspentOutputs,coinaddr); @@ -342,7 +342,7 @@ bool RewardsPlanExists(struct CCcontract_info *cp,uint64_t refsbits,CPubKey rewa txid = it->first.txhash; if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && ConstrainVout(tx.vout[0],1,CCaddr,0) != 0 ) { - char str[65]; fprintf(stderr,"rewards plan %s\n",uint256_str(str,txid)); + //char str[65]; fprintf(stderr,"rewards plan %s\n",uint256_str(str,txid)); if ( DecodeRewardsFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,sbits,APR,minseconds,maxseconds,mindeposit) == 'F' ) { if ( sbits == refsbits ) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 96d23447d..7551a3825 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5089,18 +5089,22 @@ UniValue faucetget(const UniValue& params, bool fHelp) UniValue dicefund(const UniValue& params, bool fHelp) { - UniValue result(UniValue::VOBJ); uint64_t funds; std::string hex; - if ( fHelp || params.size() > 1 ) - throw runtime_error("faucetfund amount\n"); + UniValue result(UniValue::VOBJ); int64_t funds,minbet,maxbet,maxodds,forfeitblocks; std::string hex; + if ( fHelp || params.size() != 5 ) + throw runtime_error("dicefund funds minbet maxbet maxodds forfeitblocks\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"); funds = atof(params[0].get_str().c_str()) * COIN; - //hex = DiceFund(0,funds); + minbet = atof(params[1].get_str().c_str()) * COIN; + maxbet = atof(params[2].get_str().c_str()) * COIN; + maxodds = atol(params[3].get_str().c_str()); + forfeitblocks = atol(params[4].get_str().c_str()); + hex = DiceCreateFunding(0,funds,minbet,maxbet,maxodds,forfeitblocks); if ( hex.size() > 0 ) { result.push_back(Pair("result", "success")); result.push_back(Pair("hex", hex)); - } else result.push_back(Pair("error", "couldnt create faucet funding transaction")); + } else result.push_back(Pair("error", "couldnt create dice funding transaction")); return(result); } From 0e84bf927322a769da42f8905591bd85f7a28455 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 05:09:19 -1100 Subject: [PATCH 09/20] Fix --- src/cc/dice.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 75ab8721b..4b9fbc7f2 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -144,7 +144,7 @@ bool DiceExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransaction & bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) { - uint256 txid,fundingtxid,hashBlock; uint64_t sbits,minbet,maxbet,maxodds,forfeitblocks,amount,reward,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; uint8_t funcid; CScript scriptPubKey; CTransaction fundingTx,vinTx; + uint256 txid,fundingtxid,hashBlock; int64_t minbet,maxbet,maxodds,forfeitblocks; uint64_t sbits,amount,reward,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; uint8_t funcid; CScript scriptPubKey; CTransaction fundingTx,vinTx; numvins = tx.vin.size(); numvouts = tx.vout.size(); preventCCvins = preventCCvouts = -1; @@ -365,7 +365,7 @@ UniValue DiceList() std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks) { CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits; int64_t a,b,c,d; struct CCcontract_info *cp,C; - if ( funds < 0 || minbet < 0 || maxbet < 0 || maxodds < 1 || forfeitblocks < 0 || forefeitblocks > 1440 ) + if ( funds < 0 || minbet < 0 || maxbet < 0 || maxodds < 1 || forfeitblocks < 0 || forfeitblocks > 1440 ) { fprintf(stderr,"negative parameter error\n"); return(0); @@ -423,7 +423,7 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6 std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds) { CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits; int64_t funding,minbet,maxbet,maxodds,forfeitblocks; struct CCcontract_info *cp,C; - if ( wager < 0 ) + if ( bet < 0 ) { fprintf(stderr,"negative parameter error\n"); return(0); @@ -446,7 +446,7 @@ std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet } if ( (funding= DicePlanFunds(sbits,cp,dicepk,fundingtxid)) >= bet*odds+txfee ) { - if ( AddNormalinputs(mtx,mypk,wager+2*txfee,64) > 0 ) + if ( AddNormalinputs(mtx,mypk,bet+2*txfee,64) > 0 ) { mtx.vout.push_back(MakeCC1vout(cp->evalcode,wager,dicepk)); mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); From 3f9f82297e0fedf39759cb52aa0fe2eed6ac71e0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 05:09:58 -1100 Subject: [PATCH 10/20] Test --- src/cc/dice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 4b9fbc7f2..2b596c446 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -448,10 +448,10 @@ std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet { if ( AddNormalinputs(mtx,mypk,bet+2*txfee,64) > 0 ) { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,wager,dicepk)); + mtx.vout.push_back(MakeCC1vout(cp->evalcode,bet,dicepk)); mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeDiceOpRet('L',sbits,fundingtxid))); - } else fprintf(stderr,"cant find enough inputs %.8f note enough for %.8f\n",(double)funding/COIN,(double)wager/COIN); + } else fprintf(stderr,"cant find enough inputs %.8f note enough for %.8f\n",(double)funding/COIN,(double)bet/COIN); } fprintf(stderr,"cant find dice inputs\n"); return(0); From 5bd03ad7b6c44e9f8f5defac62672fe45f68a09e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 05:13:38 -1100 Subject: [PATCH 11/20] Fix --- src/cc/CCdice.h | 2 +- src/wallet/rpcwallet.cpp | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/cc/CCdice.h b/src/cc/CCdice.h index d7666032f..4b5f108ef 100644 --- a/src/cc/CCdice.h +++ b/src/cc/CCdice.h @@ -24,6 +24,6 @@ bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); std::string DiceFund(uint64_t txfee,uint64_t funds); -std::string DiceCreateFunding(uint64_t txfee,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks); +std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks); #endif diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 7551a3825..03fc30eb9 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5090,16 +5090,17 @@ UniValue faucetget(const UniValue& params, bool fHelp) UniValue dicefund(const UniValue& params, bool fHelp) { UniValue result(UniValue::VOBJ); int64_t funds,minbet,maxbet,maxodds,forfeitblocks; std::string hex; - if ( fHelp || params.size() != 5 ) - throw runtime_error("dicefund funds minbet maxbet maxodds forfeitblocks\n"); + if ( fHelp || params.size() != 6 ) + throw runtime_error("dicefund name funds minbet maxbet maxodds forfeitblocks\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"); - funds = atof(params[0].get_str().c_str()) * COIN; - minbet = atof(params[1].get_str().c_str()) * COIN; - maxbet = atof(params[2].get_str().c_str()) * COIN; - maxodds = atol(params[3].get_str().c_str()); - forfeitblocks = atol(params[4].get_str().c_str()); - hex = DiceCreateFunding(0,funds,minbet,maxbet,maxodds,forfeitblocks); + name = (char *)params[0].get_str().c_str(); + funds = atof(params[1].get_str().c_str()) * COIN; + minbet = atof(params[2].get_str().c_str()) * COIN; + maxbet = atof(params[3].get_str().c_str()) * COIN; + maxodds = atol(params[4].get_str().c_str()); + forfeitblocks = atol(params[5].get_str().c_str()); + hex = DiceCreateFunding(0,name,funds,minbet,maxbet,maxodds,forfeitblocks); if ( hex.size() > 0 ) { result.push_back(Pair("result", "success")); From 14182ebaf1249494872e4ec6567a33d3de9bf4c2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 05:14:35 -1100 Subject: [PATCH 12/20] Test --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 03fc30eb9..7dac48746 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5089,7 +5089,7 @@ UniValue faucetget(const UniValue& params, bool fHelp) UniValue dicefund(const UniValue& params, bool fHelp) { - UniValue result(UniValue::VOBJ); int64_t funds,minbet,maxbet,maxodds,forfeitblocks; std::string hex; + UniValue result(UniValue::VOBJ); int64_t funds,minbet,maxbet,maxodds,forfeitblocks; std::string hex; char *name; if ( fHelp || params.size() != 6 ) throw runtime_error("dicefund name funds minbet maxbet maxodds forfeitblocks\n"); if ( ensure_CCrequirements() < 0 ) From 587e715dc9090156a80635c1d0eabb9f1f665f27 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 05:20:48 -1100 Subject: [PATCH 13/20] Diceaddfunds --- src/rpcserver.cpp | 1 + src/rpcserver.h | 1 + src/wallet/rpcwallet.cpp | 21 ++++++++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index a7e16652a..0330c8939 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -369,6 +369,7 @@ static const CRPCCommand vRPCCommands[] = /* dice */ { "dice", "dicefund", &dicefund, true }, + { "dice", "diceaddfunds", &diceaddfunds, true }, { "dice", "dicebet", &dicebet, true }, { "dice", "diceaddress", &diceaddress, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index 9144b874a..c0e29020e 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -235,6 +235,7 @@ extern UniValue rewardslock(const UniValue& params, bool fHelp); extern UniValue rewardsunlock(const UniValue& params, bool fHelp); extern UniValue diceaddress(const UniValue& params, bool fHelp); extern UniValue dicefund(const UniValue& params, bool fHelp); +extern UniValue diceaddfunds(const UniValue& params, bool fHelp); extern UniValue dicebet(const UniValue& params, bool fHelp); extern UniValue lottoaddress(const UniValue& params, bool fHelp); extern UniValue ponziaddress(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 7dac48746..653add7a9 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5029,7 +5029,7 @@ UniValue rewardsaddfunding(const UniValue& params, bool fHelp) { result.push_back(Pair("result", "success")); result.push_back(Pair("hex", hex)); - } else result.push_back(Pair("error", "couldnt create rewards lock transaction")); + } else result.push_back(Pair("error", "couldnt create rewards addfunding transaction")); return(result); } @@ -5109,6 +5109,25 @@ UniValue dicefund(const UniValue& params, bool fHelp) return(result); } +UniValue diceaddfunds(const UniValue& params, bool fHelp) +{ + UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid; uint64_t amount; std::string hex; + if ( fHelp || params.size() != 3 ) + throw runtime_error("diceaddfunds name fundingtxid 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"); + name = (char *)params[0].get_str().c_str(); + fundingtxid = Parseuint256((char *)params[1].get_str().c_str()); + amount = atof(params[2].get_str().c_str()) * COIN; + hex = DiceAddfunding(0,name,fundingtxid,amount); + if ( hex.size() > 0 ) + { + result.push_back(Pair("result", "success")); + result.push_back(Pair("hex", hex)); + } else result.push_back(Pair("error", "couldnt create dice addfunding transaction")); + return(result); +} + UniValue dicebet(const UniValue& params, bool fHelp) { UniValue result(UniValue::VOBJ); std::string hex; uint64_t amount,odds; From 6a046438dd5dc243975b47b901deef7eb7a41735 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 05:24:18 -1100 Subject: [PATCH 14/20] Fix --- src/cc/CCdice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/CCdice.h b/src/cc/CCdice.h index 4b5f108ef..8f76108dd 100644 --- a/src/cc/CCdice.h +++ b/src/cc/CCdice.h @@ -23,7 +23,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); -std::string DiceFund(uint64_t txfee,uint64_t funds); std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks); +std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount); #endif From c857567a626d047191eae6b2470a335b3ffdbf16 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 05:31:42 -1100 Subject: [PATCH 15/20] Dice list and dice info --- src/cc/CCdice.h | 2 ++ src/cc/dice.cpp | 2 +- src/rpcserver.cpp | 2 ++ src/rpcserver.h | 3 ++- src/wallet/rpcwallet.cpp | 33 +++++++++++++++++++++++++++------ 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/cc/CCdice.h b/src/cc/CCdice.h index 8f76108dd..14d08596a 100644 --- a/src/cc/CCdice.h +++ b/src/cc/CCdice.h @@ -25,5 +25,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks); std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount); +UniValue DiceInfo(uint256 diceid); +UniValue DiceList(); #endif diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 2b596c446..0e6669964 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -423,7 +423,7 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6 std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds) { CMutableTransaction mtx; CPubKey mypk,dicepk; CScript opret; uint64_t sbits; int64_t funding,minbet,maxbet,maxodds,forfeitblocks; struct CCcontract_info *cp,C; - if ( bet < 0 ) + if ( bet < 0 || odds < 1 ) { fprintf(stderr,"negative parameter error\n"); return(0); diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 0330c8939..580a050c3 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -368,6 +368,8 @@ static const CRPCCommand vRPCCommands[] = { "faucet", "faucetaddress", &faucetaddress, true }, /* dice */ + { "dice", "dicelist", &dicelist, true }, + { "dice", "diceinfo", &diceinfo, true }, { "dice", "dicefund", &dicefund, true }, { "dice", "diceaddfunds", &diceaddfunds, true }, { "dice", "dicebet", &dicebet, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index c0e29020e..665ae5023 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -234,7 +234,8 @@ extern UniValue rewardsaddfunding(const UniValue& params, bool fHelp); extern UniValue rewardslock(const UniValue& params, bool fHelp); extern UniValue rewardsunlock(const UniValue& params, bool fHelp); extern UniValue diceaddress(const UniValue& params, bool fHelp); -extern UniValue dicefund(const UniValue& params, bool fHelp); +extern UniValue dicelist(const UniValue& params, bool fHelp); +extern UniValue diceinfo(const UniValue& params, bool fHelp); extern UniValue diceaddfunds(const UniValue& params, bool fHelp); extern UniValue dicebet(const UniValue& params, bool fHelp); extern UniValue lottoaddress(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 653add7a9..71451cd2f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5054,6 +5054,27 @@ UniValue rewardsunlock(const UniValue& params, bool fHelp) return(result); } +UniValue rewardslist(const UniValue& params, bool fHelp) +{ + uint256 tokenid; + if ( fHelp || params.size() > 0 ) + throw runtime_error("rewardslist\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(RewardsList()); +} + +UniValue rewardsinfo(const UniValue& params, bool fHelp) +{ + uint256 fundingtxid; + if ( fHelp || params.size() != 1 ) + throw runtime_error("rewardsinfo 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(RewardsInfo(fundingtxid)); +} + UniValue faucetfund(const UniValue& params, bool fHelp) { UniValue result(UniValue::VOBJ); uint64_t funds; std::string hex; @@ -5148,25 +5169,25 @@ UniValue dicebet(const UniValue& params, bool fHelp) return(result); } -UniValue rewardslist(const UniValue& params, bool fHelp) +UniValue dicelist(const UniValue& params, bool fHelp) { uint256 tokenid; if ( fHelp || params.size() > 0 ) - throw runtime_error("rewardslist\n"); + throw runtime_error("dicelist\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(RewardsList()); + return(DiceList()); } -UniValue rewardsinfo(const UniValue& params, bool fHelp) +UniValue diceinfo(const UniValue& params, bool fHelp) { uint256 fundingtxid; if ( fHelp || params.size() != 1 ) - throw runtime_error("rewardsinfo fundingtxid\n"); + throw runtime_error("diceinfo 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(RewardsInfo(fundingtxid)); + return(DiceInfo(fundingtxid)); } UniValue tokenlist(const UniValue& params, bool fHelp) From b483858c81ea7082ae15c4211c8b70e191ef7201 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 05:34:02 -1100 Subject: [PATCH 16/20] dicefund --- src/rpcserver.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rpcserver.h b/src/rpcserver.h index 665ae5023..4da7c73c0 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -234,6 +234,7 @@ extern UniValue rewardsaddfunding(const UniValue& params, bool fHelp); extern UniValue rewardslock(const UniValue& params, bool fHelp); extern UniValue rewardsunlock(const UniValue& params, bool fHelp); extern UniValue diceaddress(const UniValue& params, bool fHelp); +extern UniValue dicefund(const UniValue& params, bool fHelp); extern UniValue dicelist(const UniValue& params, bool fHelp); extern UniValue diceinfo(const UniValue& params, bool fHelp); extern UniValue diceaddfunds(const UniValue& params, bool fHelp); From 7d82111255d52fe47c16e7e98be1499580e7b680 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 05:42:18 -1100 Subject: [PATCH 17/20] Dice bet --- src/cc/CCdice.h | 1 + src/wallet/rpcwallet.cpp | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/cc/CCdice.h b/src/cc/CCdice.h index 14d08596a..23adb0ffb 100644 --- a/src/cc/CCdice.h +++ b/src/cc/CCdice.h @@ -23,6 +23,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); +std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds); std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t forfeitblocks); std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount); UniValue DiceInfo(uint256 diceid); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 71451cd2f..58a7ad138 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5151,16 +5151,19 @@ UniValue diceaddfunds(const UniValue& params, bool fHelp) UniValue dicebet(const UniValue& params, bool fHelp) { - UniValue result(UniValue::VOBJ); std::string hex; uint64_t amount,odds; + UniValue result(UniValue::VOBJ); std::string hex; uint256 fundingtxid; uint64_t amount,odds; char *name; if ( fHelp || params.size() > 2 ) - throw runtime_error("dicebet amount odds\n"); + throw runtime_error("dicebet name fundingtxid amount odds\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"); - amount = atof(params[0].get_str().c_str()) * COIN; + name = (char *)params[0].get_str().c_str(); + fundingtxid = Parseuint256((char *)params[1].get_str().c_str()); + amount = atof(params[2].get_str().c_str()) * COIN; + odds = atol(params[3].get_str().c_str()); if ( params.size() == 2 ) odds = atof(params[1].get_str().c_str()) * COIN; else odds = 1; - //hex = DiceBet(0,amount,odds); + hex = DiceBet(0,name,fundingtxid,amount,odds); if ( hex.size() > 0 ) { result.push_back(Pair("result", "success")); From 4d5488bbab43000ac1f2ce980421b97dbec385db Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 05:45:12 -1100 Subject: [PATCH 18/20] Test --- src/wallet/rpcwallet.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 58a7ad138..9122cb916 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5160,9 +5160,6 @@ UniValue dicebet(const UniValue& params, bool fHelp) fundingtxid = Parseuint256((char *)params[1].get_str().c_str()); amount = atof(params[2].get_str().c_str()) * COIN; odds = atol(params[3].get_str().c_str()); - if ( params.size() == 2 ) - odds = atof(params[1].get_str().c_str()) * COIN; - else odds = 1; hex = DiceBet(0,name,fundingtxid,amount,odds); if ( hex.size() > 0 ) { From 135ead85b28b81af81c6089b76726808a6302034 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 05:46:28 -1100 Subject: [PATCH 19/20] Test --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 9122cb916..0bc73e9f1 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5152,7 +5152,7 @@ UniValue diceaddfunds(const UniValue& params, bool fHelp) UniValue dicebet(const UniValue& params, bool fHelp) { UniValue result(UniValue::VOBJ); std::string hex; uint256 fundingtxid; uint64_t amount,odds; char *name; - if ( fHelp || params.size() > 2 ) + if ( fHelp || params.size() != 4 ) throw runtime_error("dicebet name fundingtxid amount odds\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"); From 809f2e257b95613f31fa76285f13e7a4b7eeca0f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 29 Jul 2018 20:17:54 -1100 Subject: [PATCH 20/20] Put process block's check block call inside lock, revert mining testblockvalidity outside lock --- src/main.cpp | 6 +++--- src/miner.cpp | 19 +++++++++++++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5371bed51..79182bad8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4551,11 +4551,11 @@ bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNo auto verifier = libzcash::ProofVerifier::Disabled(); hash = pblock->GetHash(); //fprintf(stderr,"ProcessBlock %d\n",(int32_t)chainActive.LastTip()->nHeight); - if ( chainActive.LastTip() != 0 ) - komodo_currentheight_set(chainActive.LastTip()->nHeight); - checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0); { LOCK(cs_main); + if ( chainActive.LastTip() != 0 ) + komodo_currentheight_set(chainActive.LastTip()->nHeight); + checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0); bool fRequested = MarkBlockAsReceived(hash); fRequested |= fForceProcessing; if ( checked != 0 && komodo_checkPOW(0,pblock,height) < 0 ) //from_miner && ASSETCHAINS_STAKED == 0 diff --git a/src/miner.cpp b/src/miner.cpp index 1750e27ca..fb2eb2d05 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -493,8 +493,23 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount) return(0); } } + else if ( ASSETCHAINS_CC == 0 && pindexPrev != 0 && ASSETCHAINS_STAKED == 0 && (ASSETCHAINS_SYMBOL[0] != 0 || IS_KOMODO_NOTARY == 0 || My_notaryid < 0) ) + { + CValidationState state; + //fprintf(stderr,"check validity\n"); + if ( !TestBlockValidity(state, *pblock, pindexPrev, false, false)) // invokes CC checks + { + //static uint32_t counter; + //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 ) + // fprintf(stderr,"warning: miner testblockvalidity failed\n"); + fprintf(stderr,"invalid\n"); + return(0); + } + //fprintf(stderr,"valid\n"); + } } - if ( pindexPrev != 0 && ASSETCHAINS_STAKED == 0 && (ASSETCHAINS_SYMBOL[0] != 0 || IS_KOMODO_NOTARY == 0 || My_notaryid < 0) ) + /* skip checking validity outside of lock. if inside lock and CC contract is being validated, can deadlock. + if ( ASSETCHAINS_CC != 0 && pindexPrev != 0 && ASSETCHAINS_STAKED == 0 && (ASSETCHAINS_SYMBOL[0] != 0 || IS_KOMODO_NOTARY == 0 || My_notaryid < 0) ) { CValidationState state; //fprintf(stderr,"check validity\n"); @@ -507,7 +522,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount) return(0); } //fprintf(stderr,"valid\n"); - } + }*/ //fprintf(stderr,"done new block\n"); return pblocktemplate.release();