sync jl777:FSM
This commit is contained in:
125
src/cc/dice.cpp
125
src/cc/dice.cpp
@@ -98,7 +98,7 @@ What is needed is for the dealer node to track the entropy tx that was already b
|
||||
#include "../compat/endian.h"
|
||||
|
||||
#define MAX_ENTROPYUSED 8192
|
||||
#define DICE_MINUTXOS 10000
|
||||
#define DICE_MINUTXOS 15000
|
||||
extern int32_t KOMODO_INSYNC;
|
||||
|
||||
pthread_mutex_t DICE_MUTEX,DICEREVEALED_MUTEX;
|
||||
@@ -245,9 +245,12 @@ bool mySenddicetransaction(std::string res,uint256 entropyused,int32_t entropyvo
|
||||
{
|
||||
RelayTransaction(tx);
|
||||
fprintf(stderr,"rebroadcast.%c and clear [%d] and broadcast entropyused.%s bettxid.%s -> %s\n",funcid,i,entropyused.GetHex().c_str(),bettxid.GetHex().c_str(),tx.GetHash().GetHex().c_str());
|
||||
if ( ptr->rawtx.empty() == 0 )
|
||||
ptr->rawtx.clear();
|
||||
ptr->txid = zeroid;
|
||||
if ( ptr != 0 )
|
||||
{
|
||||
if ( ptr->rawtx.empty() == 0 )
|
||||
ptr->rawtx.clear();
|
||||
ptr->txid = zeroid;
|
||||
}
|
||||
//fprintf(stderr,"error adding funcid.%c E.%s bet.%s -> %s to mempool, probably Disable replacement feature size.%d\n",funcid,entropyused.GetHex().c_str(),bettxid.GetHex().c_str(),tx.GetHash().GetHex().c_str(),(int32_t)ptr->rawtx.size());
|
||||
}
|
||||
} else fprintf(stderr,"error duplicate entropyused different bettxid\n");
|
||||
@@ -540,10 +543,9 @@ CPubKey DiceFundingPk(CScript scriptPubKey)
|
||||
CPubKey pk; uint8_t *ptr,*dest; int32_t i;
|
||||
if ( scriptPubKey.size() == 35 )
|
||||
{
|
||||
ptr = (uint8_t *)scriptPubKey.data();
|
||||
dest = (uint8_t *)pk.begin();
|
||||
for (i=0; i<33; i++)
|
||||
dest[i] = ptr[i+1];
|
||||
dest[i] = scriptPubKey[i+1];
|
||||
} else fprintf(stderr,"DiceFundingPk invalid size.%d\n",(int32_t)scriptPubKey.size());
|
||||
return(pk);
|
||||
}
|
||||
@@ -831,7 +833,7 @@ bool DiceVerifyTimeout(CTransaction &betTx,int32_t timeoutblocks)
|
||||
return(numblocks >= timeoutblocks);
|
||||
}
|
||||
|
||||
bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
uint256 txid,fundingtxid,vinfundingtxid,vinhentropy,vinproof,hashBlock,hash,proof,entropy; int64_t minbet,maxbet,maxodds,timeoutblocks,odds,winnings; uint64_t vinsbits,refsbits=0,sbits,amount,inputs,outputs,txfee=10000; int32_t numvins,entropyvout,numvouts,preventCCvins,preventCCvouts,i,iswin; uint8_t funcid; CScript fundingPubKey; CTransaction fundingTx,vinTx,vinofvinTx; char CCaddr[64];
|
||||
numvins = tx.vin.size();
|
||||
@@ -917,8 +919,8 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
fprintf(stderr,"%s != %s betTx.%s\n",addr0,addr1,uint256_str(str,txid));
|
||||
fprintf(stderr,"entropyTx.%s v%d\n",uint256_str(str,tx.vin[0].prevout.hash),(int32_t)tx.vin[0].prevout.n);
|
||||
fprintf(stderr,"entropyTx vin0 %s v%d\n",uint256_str(str,vinTx.vin[0].prevout.hash),(int32_t)vinTx.vin[0].prevout.n);
|
||||
ptr0 = (uint8_t *)vinofvinTx.vout[vinTx.vin[0].prevout.n].scriptPubKey.data();
|
||||
ptr1 = (uint8_t *)fundingPubKey.data();
|
||||
ptr0 = (uint8_t *)&vinofvinTx.vout[vinTx.vin[0].prevout.n].scriptPubKey[0];
|
||||
ptr1 = (uint8_t *)&fundingPubKey[0];
|
||||
for (i=0; i<vinofvinTx.vout[vinTx.vin[0].prevout.n].scriptPubKey.size(); i++)
|
||||
fprintf(stderr,"%02x",ptr0[i]);
|
||||
fprintf(stderr," script vs ");
|
||||
@@ -972,7 +974,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
return eval->Invalid("vout[0] != inputs-txfee for loss");
|
||||
else if ( tx.vout[2].scriptPubKey != fundingPubKey )
|
||||
{
|
||||
if ( tx.vout[2].scriptPubKey.size() == 0 || ((uint8_t *)tx.vout[2].scriptPubKey.data())[0] != 0x6a )
|
||||
if ( tx.vout[2].scriptPubKey.size() == 0 || tx.vout[2].scriptPubKey[0] != 0x6a )
|
||||
return eval->Invalid("vout[2] not send to fundingPubKey for loss");
|
||||
}
|
||||
iswin = -1;
|
||||
@@ -996,7 +998,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
}
|
||||
else if ( tx.vout[3].scriptPubKey != fundingPubKey )
|
||||
{
|
||||
if ( tx.vout[3].scriptPubKey.size() == 0 || ((uint8_t *)tx.vout[3].scriptPubKey.data())[0] != 0x6a )
|
||||
if ( tx.vout[3].scriptPubKey.size() == 0 || tx.vout[3].scriptPubKey[0] != 0x6a )
|
||||
return eval->Invalid("vout[3] not send to fundingPubKey for win/timeout");
|
||||
}
|
||||
iswin = (funcid == 'W');
|
||||
@@ -1162,8 +1164,8 @@ int64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbit
|
||||
Getscriptaddress(addr1,fundingPubKey);
|
||||
if ( strcmp(addr0,addr1) != 0 )
|
||||
{
|
||||
ptr0 = (uint8_t *)vinTx.vout[1].scriptPubKey.data();
|
||||
ptr1 = (uint8_t *)fundingPubKey.data();
|
||||
ptr0 = (uint8_t *)&vinTx.vout[1].scriptPubKey[0];
|
||||
ptr1 = (uint8_t *)&fundingPubKey[0];
|
||||
for (i=0; i<vinTx.vout[1].scriptPubKey.size(); i++)
|
||||
fprintf(stderr,"%02x",ptr0[i]);
|
||||
fprintf(stderr," script vs ");
|
||||
@@ -1187,13 +1189,12 @@ int64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbit
|
||||
else
|
||||
{
|
||||
uint8_t *ptr0,*ptr1; int32_t i; char str[65];
|
||||
ptr0 = (uint8_t *)tx.vout[1].scriptPubKey.data();
|
||||
ptr1 = (uint8_t *)fundingPubKey.data();
|
||||
const CScript &s0 = tx.vout[1].scriptPubKey;
|
||||
for (i=0; i<tx.vout[1].scriptPubKey.size(); i++)
|
||||
fprintf(stderr,"%02x",ptr0[i]);
|
||||
fprintf(stderr,"%02x",s0[i]);
|
||||
fprintf(stderr," script vs ");
|
||||
for (i=0; i<fundingPubKey.size(); i++)
|
||||
fprintf(stderr,"%02x",ptr1[i]);
|
||||
fprintf(stderr,"%02x",fundingPubKey[i]);
|
||||
fprintf(stderr," (%c) tx vin.%d fundingPubKey mismatch %s\n",funcid,tx.vin[0].prevout.n,uint256_str(str,tx.vin[0].prevout.hash));
|
||||
}
|
||||
}
|
||||
@@ -1331,7 +1332,8 @@ UniValue DiceList()
|
||||
|
||||
std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t timeoutblocks)
|
||||
{
|
||||
CMutableTransaction mtx; uint256 zero; CScript fundingPubKey; CPubKey mypk,dicepk; int64_t a,b,c,d; uint64_t sbits; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
uint256 zero; CScript fundingPubKey; CPubKey mypk,dicepk; int64_t a,b,c,d; uint64_t sbits; struct CCcontract_info *cp,C;
|
||||
if ( funds < 0 || minbet < 0 || maxbet < 0 || maxodds < 1 || maxodds > 9999 || timeoutblocks < 0 || timeoutblocks > 1440 )
|
||||
{
|
||||
CCerror = "invalid parameter error";
|
||||
@@ -1365,7 +1367,8 @@ 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; CScript fundingPubKey,scriptPubKey; uint256 entropy,hentropy; CPubKey mypk,dicepk; uint64_t sbits; struct CCcontract_info *cp,C; int64_t minbet,maxbet,maxodds,timeoutblocks;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CScript fundingPubKey,scriptPubKey; uint256 entropy,hentropy; CPubKey mypk,dicepk; uint64_t sbits; struct CCcontract_info *cp,C; int64_t minbet,maxbet,maxodds,timeoutblocks;
|
||||
if ( amount < 0 )
|
||||
{
|
||||
CCerror = "amount must be positive";
|
||||
@@ -1380,18 +1383,16 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6
|
||||
if ( 0 )
|
||||
{
|
||||
uint8_t *ptr0,*ptr1; int32_t i;
|
||||
ptr0 = (uint8_t *)scriptPubKey.data();
|
||||
ptr1 = (uint8_t *)fundingPubKey.data();
|
||||
for (i=0; i<35; i++)
|
||||
fprintf(stderr,"%02x",ptr0[i]);
|
||||
fprintf(stderr,"%02x",scriptPubKey[i]);
|
||||
fprintf(stderr," script vs ");
|
||||
for (i=0; i<35; i++)
|
||||
fprintf(stderr,"%02x",ptr1[i]);
|
||||
fprintf(stderr,"%02x",fundingPubKey[i]);
|
||||
fprintf(stderr," funding\n");
|
||||
}
|
||||
if ( scriptPubKey == fundingPubKey )
|
||||
{
|
||||
if ( AddNormalinputs(mtx,mypk,amount+2*txfee,1) > 0 )
|
||||
if ( AddNormalinputs2(mtx,amount+2*txfee,60) > 0 )
|
||||
{
|
||||
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash,mtx.vin[0].prevout.n,1);
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,dicepk));
|
||||
@@ -1410,7 +1411,8 @@ 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; CScript fundingPubKey; CPubKey mypk,dicepk; uint64_t sbits,entropyval,entropyval2; int64_t funding,minbet,maxbet,maxodds,timeoutblocks; uint256 entropytxid,entropytxid2,entropy,hentropy; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CScript fundingPubKey; CPubKey mypk,dicepk; uint64_t sbits,entropyval,entropyval2; int64_t funding,minbet,maxbet,maxodds,timeoutblocks; uint256 entropytxid,entropytxid2,entropy,hentropy; struct CCcontract_info *cp,C;
|
||||
if ( bet < 0 )
|
||||
{
|
||||
CCerror = "bet must be positive";
|
||||
@@ -1468,7 +1470,8 @@ std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet
|
||||
|
||||
std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyvout,int32_t *resultp,uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid,int32_t winlosetimeout,uint256 vin0txid,int32_t vin0vout)
|
||||
{
|
||||
CMutableTransaction mtx; CScript scriptPubKey,fundingPubKey; CTransaction oldbetTx,betTx,entropyTx; uint256 hentropyproof,entropytxid,hashBlock,bettorentropy,entropy,hentropy,oldbettxid; CPubKey mypk,dicepk,fundingpk; struct CCcontract_info *cp,C; int64_t inputs=0,CCchange=0,odds,fundsneeded,minbet,maxbet,maxodds,timeoutblocks; int32_t oldentropyvout,retval=0,iswin=0; uint64_t entropyval,sbits;
|
||||
CMutableTransaction savemtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CScript scriptPubKey,fundingPubKey; CTransaction oldbetTx,betTx,entropyTx; uint256 hentropyproof,entropytxid,hashBlock,bettorentropy,entropy,hentropy,oldbettxid; CPubKey mypk,dicepk,fundingpk; struct CCcontract_info *cp,C; int64_t inputs=0,CCchange=0,odds,fundsneeded,minbet,maxbet,maxodds,timeoutblocks; int32_t oldentropyvout,retval=0,iswin=0; uint64_t entropyval,sbits;
|
||||
entropyused = zeroid;
|
||||
*resultp = 0;
|
||||
funcid = 0;
|
||||
@@ -1479,9 +1482,9 @@ std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyv
|
||||
return("");
|
||||
}
|
||||
fundingpk = DiceFundingPk(fundingPubKey);
|
||||
scriptPubKey = CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG;
|
||||
if ( winlosetimeout != 0 ) // must be dealernode
|
||||
{
|
||||
scriptPubKey = CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG;
|
||||
if ( scriptPubKey != fundingPubKey )
|
||||
{
|
||||
//fprintf(stderr,"only dice fund creator can submit winner or loser\n");
|
||||
@@ -1502,7 +1505,7 @@ std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyv
|
||||
{
|
||||
if ( vin0txid == zeroid || vin0vout < 0 )
|
||||
{
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,1) == 0 ) // must be a single vin!!
|
||||
if ( AddNormalinputs2(mtx,2*txfee,3) == 0 ) // must be a single vin!!
|
||||
{
|
||||
CCerror = "no txfee inputs for win/lose";
|
||||
fprintf(stderr,"%s\n", CCerror.c_str() );
|
||||
@@ -1583,6 +1586,7 @@ std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyv
|
||||
}
|
||||
CCchange = betTx.vout[0].nValue + betTx.vout[1].nValue;
|
||||
fundsneeded = txfee + (odds+1)*betTx.vout[1].nValue;
|
||||
savemtx = mtx;
|
||||
if ( CCchange >= fundsneeded )
|
||||
CCchange -= fundsneeded;
|
||||
else if ( (inputs= AddDiceInputs(cp,mtx,dicepk,fundsneeded,1,sbits,fundingtxid)) >= fundsneeded )
|
||||
@@ -1592,6 +1596,7 @@ std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyv
|
||||
}
|
||||
else
|
||||
{
|
||||
mtx = savemtx;
|
||||
if ( (inputs= AddDiceInputs(cp,mtx,dicepk,fundsneeded,60,sbits,fundingtxid)) > 0 )
|
||||
{
|
||||
if ( inputs > fundsneeded )
|
||||
@@ -1617,6 +1622,15 @@ std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyv
|
||||
//fprintf(stderr,"make tx.%c\n",funcid);
|
||||
if ( funcid == 'L' || funcid == 'W' ) // dealernode only
|
||||
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash,mtx.vin[0].prevout.n,1);
|
||||
else
|
||||
{
|
||||
if ( scriptPubKey != betTx.vout[2].scriptPubKey )
|
||||
{
|
||||
CCerror = strprintf("can only finish your own bettxid\n");
|
||||
fprintf(stderr,"%s\n", CCerror.c_str() );
|
||||
return("");
|
||||
}
|
||||
}
|
||||
*resultp = 1;
|
||||
//char str[65],str2[65];
|
||||
//fprintf(stderr,"iswin.%d house entropy %s vs bettor %s\n",iswin,uint256_str(str,hentropyproof),uint256_str(str2,bettorentropy));
|
||||
@@ -1638,22 +1652,32 @@ static uint256 dealer0_fundingtxid;
|
||||
void *dealer0_loop(void *_arg)
|
||||
{
|
||||
char *planstr = (char *)_arg;
|
||||
CTransaction tx; CPubKey mypk,dicepk; uint64_t entropyval; uint256 entropytxid; int32_t entropytxs,i,n,num; CScript fundingPubKey; struct CCcontract_info *cp,C; char coinaddr[64]; std::string res; int64_t minbet,maxbet,maxodds,timeoutblocks; uint64_t refsbits,txfee = 10000;
|
||||
CTransaction tx,*entropytxs,entropytx; CPubKey mypk,dicepk; uint64_t entropyval; uint256 hashBlock,entropytxid,txid; int32_t height,lastht,numentropytxs,i,n,m,num; CScript fundingPubKey; struct CCcontract_info *cp,C; char coinaddr[64]; std::string res; int64_t minbet,maxbet,maxodds,timeoutblocks; uint64_t refsbits,txfee = 10000;
|
||||
if ( (cp= Diceinit(fundingPubKey,dealer0_fundingtxid,&C,planstr,txfee,mypk,dicepk,refsbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 )
|
||||
{
|
||||
fprintf(stderr,"error initializing dealer0_loop\n");
|
||||
exit(-1);
|
||||
}
|
||||
fprintf(stderr,"dealer0 node running\n");
|
||||
height = lastht = 0;
|
||||
entropytxs = (CTransaction *)calloc(sizeof(*entropytxs),DICE_MINUTXOS);
|
||||
while ( 1 )
|
||||
{
|
||||
DicePlanFunds(entropyval,entropytxid,refsbits,cp,dicepk,dealer0_fundingtxid,entropytxs,false);
|
||||
if ( entropytxs < DICE_MINUTXOS )
|
||||
while ( KOMODO_INSYNC == 0 || (height= KOMODO_INSYNC) == lastht )
|
||||
{
|
||||
n = sqrt(DICE_MINUTXOS - entropytxs) + 10;
|
||||
for (i=0; i<DICE_MINUTXOS - entropytxs && i<n; i++)
|
||||
sleep(3);
|
||||
}
|
||||
lastht = height;
|
||||
fprintf(stderr,"New height.%d\n",height);
|
||||
DicePlanFunds(entropyval,entropytxid,refsbits,cp,dicepk,dealer0_fundingtxid,numentropytxs,false);
|
||||
if ( numentropytxs < DICE_MINUTXOS )
|
||||
{
|
||||
n = sqrt(DICE_MINUTXOS - numentropytxs);
|
||||
//if ( n > 10 )
|
||||
// n = 10;
|
||||
for (i=m=0; i<DICE_MINUTXOS - numentropytxs && i<n; i++)
|
||||
{
|
||||
res = DiceAddfunding(txfee,planstr,dealer0_fundingtxid,COIN/100);
|
||||
res = DiceAddfunding(txfee,planstr,dealer0_fundingtxid,COIN);
|
||||
if ( res.empty() == 0 && res.size() > 64 && is_hexstr((char *)res.c_str(),0) > 64 )
|
||||
{
|
||||
if ( DecodeHexTx(tx,res) != 0 )
|
||||
@@ -1661,12 +1685,37 @@ void *dealer0_loop(void *_arg)
|
||||
LOCK(cs_main);
|
||||
if ( myAddtomempool(tx) != 0 )
|
||||
{
|
||||
fprintf(stderr,"ENTROPY %s: %d of %d, %d\n",tx.GetHash().GetHex().c_str(),i,n,DICE_MINUTXOS - entropytxs);
|
||||
fprintf(stderr,"ENTROPY %s: %d of %d, %d\n",tx.GetHash().GetHex().c_str(),i,n,DICE_MINUTXOS - numentropytxs);
|
||||
RelayTransaction(tx);
|
||||
entropytxs[m++] = tx;
|
||||
} else break;
|
||||
} else break;
|
||||
} else break;
|
||||
}
|
||||
for (i=0; i<m; i++)
|
||||
{
|
||||
tx = entropytxs[i];
|
||||
txid = tx.GetHash();
|
||||
fprintf(stderr,"check %d of %d: %s\n",i,m,txid.GetHex().c_str());
|
||||
while ( 1 )
|
||||
{
|
||||
if ( myGetTransaction(txid,entropytx,hashBlock) == 0 || hashBlock == zeroid )
|
||||
{
|
||||
LOCK(cs_main);
|
||||
if ( myAddtomempool(tx) != 0 )
|
||||
{
|
||||
fprintf(stderr,"resend ENTROPY %s: %d of %d\n",txid.GetHex().c_str(),i,m);
|
||||
RelayTransaction(tx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"found %s in %s\n",txid.GetHex().c_str(),hashBlock.GetHex().c_str());
|
||||
break;
|
||||
}
|
||||
sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
pubkey2addr(coinaddr,Mypubkey().data());
|
||||
dicefinish_utxosget(num,0,0,coinaddr);
|
||||
@@ -1712,6 +1761,12 @@ double DiceStatus(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettx
|
||||
GetCCaddress(cp,coinaddr,dicepk);
|
||||
if ( bettxid == zeroid ) // scan
|
||||
{
|
||||
if ( fundingpk != mypk )
|
||||
{
|
||||
CCerror = "Diceinit error in status, non-dealer must provide bettxid";
|
||||
fprintf(stderr,"%s\n", CCerror.c_str() );
|
||||
return(0.);
|
||||
}
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
|
||||
Reference in New Issue
Block a user