From 8e6f5a6a2dd9e45b90c7d4d7d603f0901a157941 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Tue, 26 Mar 2019 20:59:31 +0800 Subject: [PATCH] initial commit for backup release tx needs testing, i think it half works. --- src/cc/CCinclude.h | 1 + src/cc/CCutils.cpp | 14 +++++++++++++- src/cc/payments.cpp | 6 ++++-- src/cc/rewards.cpp | 21 +++++++-------------- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 13d7236d4..839fd2c95 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -247,6 +247,7 @@ void CCaddrTokens1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, c int32_t CClib_initcp(struct CCcontract_info *cp,uint8_t evalcode); bool IsCCInput(CScript const& scriptSig); +bool CheckTxFee(const CTransaction &tx, uint64_t txfee, uint32_t height, uint64_t blocktime); int32_t unstringbits(char *buf,uint64_t bits); uint64_t stringbits(char *str); uint256 revuint256(uint256 txid); diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index a3bf0a68b..887550a0c 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -168,6 +168,18 @@ bool IsCCInput(CScript const& scriptSig) return true; } +bool CheckTxFee(const CTransaction &tx, uint64_t txfee, uint32_t height, uint64_t blocktime) +{ + int64_t interest; uint64_t valuein; + CCoinsViewCache &view = *pcoinsTip; + valuein = view.GetValueIn(height,&interest,tx,blocktime); + if ( valuein-tx.GetValueOut() > txfee ) + { + //fprintf(stderr, "txfee.%li vs txfee.%li\n", valuein-tx.GetValueOut(), txfee); + return false; + } + return true; +} // set additional 'unspendable' addr void CCaddr2set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr) @@ -668,4 +680,4 @@ bool CClib_Dispatch(const CC *cond,Eval *eval,std::vector paramsNull,co return(false); //eval->Invalid("error in CClib_validate"); } return eval->Invalid("cclib CC must have evalcode between 16 and 127"); -} \ No newline at end of file +} diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 184c92d33..e0c4c8ada 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -192,7 +192,9 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & if ( tmptx.vout.size() > 0 && DecodePaymentsOpRet(tmptx.vout[tmptx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) != 0 ) { if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 ) - return(eval->Invalid("negative values")); + return(eval->Invalid("negative values")); + if ( !CheckTxFee(tx, PAYMENTS_TXFEE, chainActive.LastTip()->GetHeight(), chainActive.LastTip()->nTime) ) + return eval->Invalid("txfee is too high"); Paymentspk = GetUnspendable(cp,0); //fprintf(stderr, "lockedblocks.%i minrelease.%i totalallocations.%i txidopret1.%s txidopret2.%s\n",lockedblocks, minrelease, totalallocations, txidoprets[0].ToString().c_str(), txidoprets[1].ToString().c_str() ); @@ -281,7 +283,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & fprintf(stderr, "vin.%i is not a payments CC vout: txid.%s\n", i, txin.GetHash().ToString().c_str()); return(eval->Invalid("vin is not paymentsCC type")); } //else fprintf(stderr, "vin.%i opret type txid.%s\n", i, txin.GetHash().ToString().c_str()); - } + } // check the chain depth vs locked blcoks requirement. CBlockIndex* pblockindex = mapBlockIndex[blockhash]; if ( pblockindex->GetHeight() > ht-lockedblocks ) diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index 65e32ee27..db64127e7 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -197,9 +197,6 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t uint256 txid,fundingtxid,hashBlock,vinfundingtxid; uint64_t vinsbits,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(); - int64_t interest; uint64_t valuein; - CCoinsViewCache &view = *pcoinsTip; - valuein = view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime); preventCCvins = preventCCvouts = -1; if ( numvouts < 1 ) return eval->Invalid("no vouts"); @@ -258,20 +255,17 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t if ( (*cp->ismyvin)(tx.vin[i].scriptSig) == 0 ) return eval->Invalid("unexpected normal vin for unlock"); } - if ( valuein-tx.GetValueOut() > txfee ) + if ( !CheckTxFee(tx, txfee, chainActive.LastTip()->GetHeight(), chainActive.LastTip()->nTime) ) + return eval->Invalid("txfee is too high"); + if ( numvins == 1 && tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 && tx.vout[1].nValue == 10000 ) { - fprintf(stderr, "valueout.%li vs valuein.%li txfee.%li\n", tx.GetValueOut(), valuein, txfee); - return eval->Invalid("alright is stealing your money"); - } - if ( numvouts == 2 && numvins == 1 ) - { - if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 ) - return eval->Invalid("unlock recover tx vout.0 is not normal output"); + if ( tx.vout[1].scriptPubKey != tx.vout[0].scriptPubKey ) + return eval->Invalid("unlock recover tx vout.1 mismatched scriptPubKey"); else if ( tx.vout[0].scriptPubKey != vinTx.vout[1].scriptPubKey ) return eval->Invalid("unlock recover tx vout.0 mismatched scriptPubKey"); else if ( tx.vout[0].nValue > vinTx.vout[0].nValue ) return eval->Invalid("unlock recover tx vout.0 mismatched amounts"); - else if ( tx.vout[1].nValue > 0 ) + else if ( tx.vout[2].nValue > 0 ) return eval->Invalid("unlock recover tx vout.1 nonz amount"); else return(true); } @@ -689,8 +683,7 @@ std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint2 } else { - firstmtx.vout.push_back(CTxOut(amount-txfee,scriptPubKey)); - //CCerror = "cant find enough rewards inputs"; + firstmtx.vout.push_back(CTxOut(amount-txfee*2,scriptPubKey)); fprintf(stderr,"not enough rewards funds to payout %.8f, recover mode tx\n",(double)(reward+txfee)/COIN); return(FinalizeCCTx(-1LL,cp,firstmtx,mypk,txfee,EncodeRewardsOpRet('U',sbits,fundingtxid))); }