diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 3954068e1..761e64bcd 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -28,6 +28,7 @@ #include #include +extern int32_t KOMODO_CONNECTING; #define SMALLVAL 0.000000000000001 union _bits256 { uint8_t bytes[32]; uint16_t ushorts[16]; uint32_t uints[8]; uint64_t ulongs[4]; uint64_t txid; }; diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 8cb06ab25..54a9a0225 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -255,7 +255,16 @@ CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv) bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector paramsNull,const CTransaction &ctx, unsigned int nIn) { - CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t i,n; int64_t amount; std::vector origpubkey; + CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t height,i,n,from_mempool = 0; int64_t amount; std::vector origpubkey; + if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation + return(true); + height = KOMODO_CONNECTING; + if ( (KOMODO_CONNECTING & (1<<30)) != 0 ) + { + from_mempool = 1; + height &= ((1<<30) - 1); + } + fprintf(stderr,"KOMODO_CONNECTING.%d mempool.%d\n",height,from_mempool); // there is a chance CC tx is valid in mempool, but invalid when in block, so we cant filter duplicate requests. if any of the vins are spent, for example //txid = ctx.GetHash(); //if ( txid == cp->prevtxid ) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index c2f055d8d..8da052c86 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -225,9 +225,14 @@ uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv) // max 1 vout per tx return(hentropy); } +int32_t dice_5nibbles(uint8_t *fivevals) +{ + return(((int32_t)fivevals[0]<<16) + ((int32_t)fivevals[1]<<12) + ((int32_t)fivevals[2]<<8) + ((int32_t)fivevals[3]<<4) + ((int32_t)fivevals[4])); +} + uint64_t DiceCalc(int64_t bet,int64_t odds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t timeoutblocks,uint256 houseentropy,uint256 bettorentropy) { - uint8_t buf[64],_house[32],_bettor[32]; uint64_t winnings; arith_uint256 house,bettor; char str[65],str2[65]; + uint8_t buf[64],_house[32],_bettor[32],_hash[32],hash[32],hash16[64]; uint64_t winnings; arith_uint256 house,bettor; char str[65],str2[65]; int32_t i,modval; if ( odds < 10000 ) return(0); else odds -= 10000; @@ -247,11 +252,43 @@ uint64_t DiceCalc(int64_t bet,int64_t odds,int64_t minbet,int64_t maxbet,int64_t endiancpy(&buf[32],(uint8_t *)&houseentropy,32); vcalc_sha256(0,(uint8_t *)&_bettor,buf,64); endiancpy((uint8_t *)&bettor,_bettor,32); + winnings = 0; if ( odds > 1 ) - bettor = (bettor / arith_uint256(odds)); - if ( bettor >= house ) + { + if ( 0 ) + { // old way + bettor = (bettor / arith_uint256(odds)); + if ( bettor >= house ) + winnings = bet * (odds+1); + return(winnings); + } + if ( odds > 9999 ) // shouldnt happen + return(0); + endiancpy(buf,(uint8_t *)&house,32); + endiancpy(&buf[32],(uint8_t *)&bettor,32); + vcalc_sha256(0,(uint8_t *)&_hash,buf,64); + endiancpy(hash,_hash,32); + for (i=0; i<32; i++) + { + hash16[i<<1] = ((hash[i] >> 4) & 0x0f); + hash16[(i<<1) + 1] = (hash[i] & 0x0f); + } + modval = 0; + for (i=0; i<12; i++) + { + modval = dice_5nibbles(&hash16[i*5]); + if ( modval < 1000000 ) + { + modval %= 10000; + break; + } + } + fprintf(stderr,"modval %d vs %d\n",modval,(int32_t)(10000/(odds+1))); + if ( modval < 10000/(odds+1) ) + winnings = bet * (odds+1); + } + else if ( bettor >= house ) winnings = bet * (odds+1); - else winnings = 0; return(winnings); } @@ -424,6 +461,8 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx) return eval->Invalid("cant find fundingtxid"); else if ( fundingTx.vout.size() > 0 && DecodeDiceFundingOpRet(fundingTx.vout[fundingTx.vout.size()-1].scriptPubKey,sbits,minbet,maxbet,maxodds,timeoutblocks) != 'F' ) return eval->Invalid("fundingTx not valid"); + if ( maxodds > 9999 ) + return eval->Invalid("maxodds too big"); fundingPubKey = fundingTx.vout[1].scriptPubKey; switch ( funcid ) { @@ -816,7 +855,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 timeoutblocks) { CMutableTransaction mtx; 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 || timeoutblocks < 0 || timeoutblocks > 1440 ) + if ( funds < 0 || minbet < 0 || maxbet < 0 || maxodds < 1 || maxodds > 9999 || timeoutblocks < 0 || timeoutblocks > 1440 ) { fprintf(stderr,"negative parameter error\n"); return(""); @@ -840,7 +879,7 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6 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; if ( amount < 0 ) { - fprintf(stderr,"negative parameter error\n"); + fprintf(stderr,"negative parameter\n"); return(""); } if ( (cp= Diceinit(fundingPubKey,fundingtxid,&C,planstr,txfee,mypk,dicepk,sbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 ) @@ -874,9 +913,9 @@ 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; int64_t funding,minbet,maxbet,maxodds,timeoutblocks; uint256 entropytxid,entropy,hentropy; struct CCcontract_info *cp,C; - if ( bet < 0 || odds < 1 ) + if ( bet < 0 || odds < 1 || odds > 9999 ) { - fprintf(stderr,"negative parameter error\n"); + fprintf(stderr,"negative parameter or odds too big error\n"); return(""); } if ( (cp= Diceinit(fundingPubKey,fundingtxid,&C,planstr,txfee,mypk,dicepk,sbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 ) diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 6a8ef310b..20ece62d2 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -755,6 +755,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim if ( height > 1 && checktoshis == 0 ) { checktoshis = ((uint64_t)GetBlockSubsidy(height, Params().GetConsensus()) - block.vtx[0].vout[0].nValue); + //checktoshis += txn_count * 0.001; // rely on higher level validations to prevent emitting more coins than actual txfees } if ( height >= 2 && (overflow != 0 || total > checktoshis || strangeout != 0) ) { diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 86c168a85..2d64bc8fc 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -45,7 +45,7 @@ struct komodo_state KOMODO_STATES[34]; #define _COINBASE_MATURITY 100 int COINBASE_MATURITY = _COINBASE_MATURITY;//100; -int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND; +int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,KOMODO_CONNECTING = -1; int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,JUMBLR_PAUSE = 1; std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY; uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE; diff --git a/src/main.cpp b/src/main.cpp index 6dcd6b13b..548ce2011 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -56,7 +56,7 @@ using namespace std; CCriticalSection cs_main; extern uint8_t NOTARY_PUBKEY33[33]; -extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC; +extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING; int32_t KOMODO_NEWBLOCKS; int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block); void komodo_broadcast(CBlock *pblock,int32_t limit); @@ -1263,7 +1263,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if (pfMissingInputs) *pfMissingInputs = false; - int nextBlockHeight = chainActive.Height() + 1; + int flag=0,nextBlockHeight = chainActive.Height() + 1; auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus()); // Node operator can choose to reject tx by number of transparent inputs @@ -1285,7 +1285,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } if (!CheckTransaction(tx, state, verifier)) { - return error("AcceptToMemoryPool: CheckTransaction failed"); } // DoS level set to 10 to be more forgiving. @@ -1294,7 +1293,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa { return error("AcceptToMemoryPool: ContextualCheckTransaction failed"); } - + // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) { @@ -1527,12 +1526,20 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // invalid blocks, however allowing such transactions into the mempool // can be exploited as a DoS attack. // XXX: is this neccesary for CryptoConditions? + if ( KOMODO_CONNECTING <= 0 && chainActive.LastTip() != 0 ) + { + flag = 1; + KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.LastTip()->nHeight + 1; + } if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId)) { - fprintf(stderr,"accept failure.10\n"); + if ( flag != 0 ) + KOMODO_CONNECTING = -1; return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString()); } - + if ( flag != 0 ) + KOMODO_CONNECTING = -1; + // Store transaction in memory if ( komodo_is_notarytx(tx) == 0 ) KOMODO_ON_DEMAND++; @@ -3448,6 +3455,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * return AbortNode(state, "Failed to read block"); pblock = █ } + KOMODO_CONNECTING = (int32_t)pindexNew->nHeight; // Get the current commitment tree ZCIncrementalMerkleTree oldTree; assert(pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), oldTree)); @@ -3458,6 +3466,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * { CCoinsViewCache view(pcoinsTip); bool rv = ConnectBlock(*pblock, state, pindexNew, view, false, true); + KOMODO_CONNECTING = -1; GetMainSignals().BlockChecked(*pblock, state); if (!rv) { if (state.IsInvalid()) @@ -4158,17 +4167,32 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C // Check transactions if ( ASSETCHAINS_CC != 0 ) // CC contracts might refer to transactions in the current block, from a CC spend within the same block and out of order { - CValidationState stateDummy; + CValidationState stateDummy; int32_t i,j,rejects=0,lastrejects=0; //fprintf(stderr,"put block's tx into mempool\n"); - for (int i = 0; i < block.vtx.size(); i++) + while ( 1 ) { - const CTransaction &tx = block.vtx[i]; - if (tx.IsCoinBase() != 0 ) - continue; - else if ( ASSETCHAINS_STAKED != 0 && (i == (block.vtx.size() - 1)) && komodo_isPoS((CBlock *)&block) != 0 ) - continue; - AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL); - } + for (i=0; i all tx in mempool\n",lastrejects); + break; + } + fprintf(stderr,"addtomempool ht.%d for CC checking: n.%d rejects.%d last.%d\n",height,(int32_t)block.vtx.size(),rejects,lastrejects); + lastrejects = rejects; + rejects = 0; + } //fprintf(stderr,"done putting block's tx into mempool\n"); } BOOST_FOREACH(const CTransaction& tx, block.vtx)