Merge pull request #1 from miketout/dev

pull latest komodo and miketout changes
This commit is contained in:
miketout
2018-05-04 17:17:41 -07:00
committed by GitHub
18 changed files with 132 additions and 101 deletions

View File

@@ -85,6 +85,7 @@ extern uint32_t ASSETCHAINS_MAGIC;
extern uint64_t ASSETCHAINS_SUPPLY; extern uint64_t ASSETCHAINS_SUPPLY;
extern uint64_t ASSETCHAINS_ALGO; extern uint64_t ASSETCHAINS_ALGO;
extern uint64_t ASSETCHAINS_EQUIHASH; extern uint64_t ASSETCHAINS_EQUIHASH;
extern uint64_t ASSETCHAINS_VERUSHASH;
const arith_uint256 maxUint = UintToArith256(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); const arith_uint256 maxUint = UintToArith256(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
@@ -100,7 +101,10 @@ public:
consensus.nMajorityEnforceBlockUpgrade = 750; consensus.nMajorityEnforceBlockUpgrade = 750;
consensus.nMajorityRejectBlockOutdated = 950; consensus.nMajorityRejectBlockOutdated = 950;
consensus.nMajorityWindow = 4000; consensus.nMajorityWindow = 4000;
consensus.powLimit = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"); if (ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASH)
consensus.powLimit = uint256S("00000f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
else
consensus.powLimit = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
consensus.nPowAveragingWindow = 17; consensus.nPowAveragingWindow = 17;
consensus.nMaxFutureBlockTime = 7 * 60; // 7 mins consensus.nMaxFutureBlockTime = 7 * 60; // 7 mins
@@ -182,7 +186,7 @@ public:
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main)); vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
//fMiningRequiresPeers = true; fMiningRequiresPeers = true;
fDefaultConsistencyChecks = false; fDefaultConsistencyChecks = false;
fRequireStandard = true; fRequireStandard = true;
fMineBlocksOnDemand = false; fMineBlocksOnDemand = false;

View File

@@ -117,14 +117,14 @@ int64_t komodo_current_supply(uint32_t nHeight)
int32_t baseid; int32_t baseid;
if ( (baseid = komodo_baseid(ASSETCHAINS_SYMBOL)) >= 0 && baseid < 32 ) if ( (baseid = komodo_baseid(ASSETCHAINS_SYMBOL)) >= 0 && baseid < 32 )
cur_money = ASSETCHAINS_SUPPLY + nHeight * ASSETCHAINS_REWARD[0] / SATOSHIDEN; cur_money = ASSETCHAINS_GENESISTXVAL + ASSETCHAINS_SUPPLY + nHeight * ASSETCHAINS_REWARD[0] / SATOSHIDEN;
else else
{ {
// figure out max_money by adding up supply to a maximum of 10,000,000 blocks // figure out max_money by adding up supply to a maximum of 10,000,000 blocks
cur_money = (ASSETCHAINS_SUPPLY+1) * SATOSHIDEN + (ASSETCHAINS_MAGIC & 0xffffff) + ASSETCHAINS_GENESISTXVAL; cur_money = (ASSETCHAINS_SUPPLY+1) * SATOSHIDEN + (ASSETCHAINS_MAGIC & 0xffffff) + ASSETCHAINS_GENESISTXVAL;
if ( ASSETCHAINS_LASTERA == 0 && ASSETCHAINS_REWARD[0] == 0 ) if ( ASSETCHAINS_LASTERA == 0 && ASSETCHAINS_REWARD[0] == 0 )
{ {
cur_money = ASSETCHAINS_SUPPLY + (nHeight * 10000) / SATOSHIDEN; cur_money += (nHeight * 10000) / SATOSHIDEN;
} }
else else
{ {

View File

@@ -80,13 +80,15 @@ uint64_t komodo_moneysupply(int32_t height)
} }
#endif #endif
uint64_t _komodo_interestnew(uint64_t nValue,uint32_t nLockTime,uint32_t tiptime) uint64_t _komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime)
{ {
int32_t minutes; uint64_t interest = 0; int32_t minutes; uint64_t interest = 0;
if ( nLockTime >= LOCKTIME_THRESHOLD && tiptime > nLockTime && (minutes= (tiptime - nLockTime) / 60) >= 60 ) if ( nLockTime >= LOCKTIME_THRESHOLD && tiptime > nLockTime && (minutes= (tiptime - nLockTime) / 60) >= 60 )
{ {
if ( minutes > 365 * 24 * 60 ) if ( minutes > 365 * 24 * 60 )
minutes = 365 * 24 * 60; minutes = 365 * 24 * 60;
if ( txheight >= 1000000 && minutes > 31 * 24 * 60 )
minutes = 31 * 24 * 60;
minutes -= 59; minutes -= 59;
interest = ((nValue / 10512000) * minutes); interest = ((nValue / 10512000) * minutes);
} }
@@ -97,7 +99,7 @@ uint64_t komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime,
{ {
uint64_t interest = 0; uint64_t interest = 0;
if ( txheight < KOMODO_ENDOFERA && nLockTime >= LOCKTIME_THRESHOLD && tiptime != 0 && nLockTime < tiptime && nValue >= 10*COIN ) //komodo_moneysupply(txheight) < MAX_MONEY && if ( txheight < KOMODO_ENDOFERA && nLockTime >= LOCKTIME_THRESHOLD && tiptime != 0 && nLockTime < tiptime && nValue >= 10*COIN ) //komodo_moneysupply(txheight) < MAX_MONEY &&
interest = _komodo_interestnew(nValue,nLockTime,tiptime); interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
return(interest); return(interest);
} }
@@ -151,21 +153,21 @@ uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uin
else if ( txheight < 1000000 ) else if ( txheight < 1000000 )
{ {
interest = (numerator * minutes) / ((uint64_t)365 * 24 * 60); interest = (numerator * minutes) / ((uint64_t)365 * 24 * 60);
interestnew = _komodo_interestnew(nValue,nLockTime,tiptime); interestnew = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
if ( interest < interestnew ) if ( interest < interestnew )
printf("pathA current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n",dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime); printf("pathA current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n",dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime);
} }
else interest = _komodo_interestnew(nValue,nLockTime,tiptime); else interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
} }
else if ( txheight < 1000000 ) else if ( txheight < 1000000 )
{ {
numerator = (nValue * KOMODO_INTEREST); numerator = (nValue * KOMODO_INTEREST);
interest = (numerator / denominator) / COIN; interest = (numerator / denominator) / COIN;
interestnew = _komodo_interestnew(nValue,nLockTime,tiptime); interestnew = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
if ( interest < interestnew ) if ( interest < interestnew )
printf("pathB current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n",dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime); printf("pathB current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n",dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime);
} }
else interest = _komodo_interestnew(nValue,nLockTime,tiptime); else interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
} }
else else
{ {
@@ -187,11 +189,11 @@ uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uin
numerator = (nValue / 20); // assumes 5%! numerator = (nValue / 20); // assumes 5%!
interest = ((numerator * minutes) / ((uint64_t)365 * 24 * 60)); interest = ((numerator * minutes) / ((uint64_t)365 * 24 * 60));
//fprintf(stderr,"interest %llu %.8f <- numerator.%llu minutes.%d\n",(long long)interest,(double)interest/COIN,(long long)numerator,(int32_t)minutes); //fprintf(stderr,"interest %llu %.8f <- numerator.%llu minutes.%d\n",(long long)interest,(double)interest/COIN,(long long)numerator,(int32_t)minutes);
interestnew = _komodo_interestnew(nValue,nLockTime,tiptime); interestnew = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
if ( interest < interestnew ) if ( interest < interestnew )
fprintf(stderr,"pathC current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n",dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime); fprintf(stderr,"pathC current interest %.8f vs new %.8f for ht.%d %.8f locktime.%u tiptime.%u\n",dstr(interest),dstr(interestnew),txheight,dstr(nValue),nLockTime,tiptime);
} }
else interest = _komodo_interestnew(nValue,nLockTime,tiptime); else interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
} }
if ( 0 && numerator == (nValue * KOMODO_INTEREST) ) if ( 0 && numerator == (nValue * KOMODO_INTEREST) )
fprintf(stderr,"komodo_interest.%d %lld %.8f nLockTime.%u tiptime.%u minutes.%d interest %lld %.8f (%llu / %llu) prod.%llu\n",txheight,(long long)nValue,(double)nValue/COIN,nLockTime,tiptime,minutes,(long long)interest,(double)interest/COIN,(long long)numerator,(long long)denominator,(long long)(numerator * minutes)); fprintf(stderr,"komodo_interest.%d %lld %.8f nLockTime.%u tiptime.%u minutes.%d interest %lld %.8f (%llu / %llu) prod.%llu\n",txheight,(long long)nValue,(double)nValue/COIN,nLockTime,tiptime,minutes,(long long)interest,(double)interest/COIN,(long long)numerator,(long long)denominator,(long long)(numerator * minutes));

View File

@@ -1733,6 +1733,11 @@ void komodo_args(char *argv0)
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_DECAY[i]),(void *)&ASSETCHAINS_DECAY[i]); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_DECAY[i]),(void *)&ASSETCHAINS_DECAY[i]);
} }
if (ASSETCHAINS_LASTERA > 0)
{
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_LASTERA),(void *)&ASSETCHAINS_LASTERA);
}
// hash in lock above for time locked coinbase transactions above a certain reward value only if the lock above // hash in lock above for time locked coinbase transactions above a certain reward value only if the lock above
// param was specified, otherwise, for compatibility, do nothing // param was specified, otherwise, for compatibility, do nothing
if ( ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF ) if ( ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF )
@@ -1777,7 +1782,8 @@ void komodo_args(char *argv0)
if ( (port= komodo_userpass(ASSETCHAINS_USERPASS,ASSETCHAINS_SYMBOL)) != 0 ) if ( (port= komodo_userpass(ASSETCHAINS_USERPASS,ASSETCHAINS_SYMBOL)) != 0 )
ASSETCHAINS_RPCPORT = port; ASSETCHAINS_RPCPORT = port;
else komodo_configfile(ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT + 1); else komodo_configfile(ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT + 1);
COINBASE_MATURITY = 1; if (ASSETCHAINS_LASTERA == 0 && ASSETCHAINS_REWARD[0] == 0)
COINBASE_MATURITY = 1;
//fprintf(stderr,"ASSETCHAINS_RPCPORT (%s) %u\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_RPCPORT); //fprintf(stderr,"ASSETCHAINS_RPCPORT (%s) %u\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_RPCPORT);
} }
if ( ASSETCHAINS_RPCPORT == 0 ) if ( ASSETCHAINS_RPCPORT == 0 )

View File

@@ -2056,6 +2056,14 @@ namespace Consensus {
error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight), error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
REJECT_INVALID, "bad-txns-premature-spend-of-coinbase"); REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
} }
// ensure that zeroth output of coinbases are not still time locked
uint64_t unlockTime = tx.UnlockTime(0);
if (nSpendHeight >= unlockTime) {
return state.Invalid(
error("CheckInputs(): tried to spend coinbase that is timelocked until block %d", unlockTime),
REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
}
// Ensure that coinbases cannot be spent to transparent outputs // Ensure that coinbases cannot be spent to transparent outputs
// Disabled on regtest // Disabled on regtest

View File

@@ -24,6 +24,9 @@
#endif #endif
#include <unistd.h> #include <unistd.h>
extern int64_t ASSETCHAINS_TIMELOCKGTE;
int64_t komodo_block_unlocktime(uint32_t nHeight);
void AtomicTimer::start() void AtomicTimer::start()
{ {
std::unique_lock<std::mutex> lock(mtx); std::unique_lock<std::mutex> lock(mtx);
@@ -335,7 +338,9 @@ int printMetrics(size_t cols, bool mining)
if ((height > 0) && (height <= consensusParams.GetLastFoundersRewardBlockHeight())) { if ((height > 0) && (height <= consensusParams.GetLastFoundersRewardBlockHeight())) {
subsidy -= subsidy/5; subsidy -= subsidy/5;
} }
if (std::max(0, COINBASE_MATURITY - (tipHeight - height)) > 0) {
if ((std::max(0, COINBASE_MATURITY - (tipHeight - height)) > 0) ||
(tipHeight < komodo_block_unlocktime(height) && subsidy >= ASSETCHAINS_TIMELOCKGTE)) {
immature += subsidy; immature += subsidy;
} else { } else {
mature += subsidy; mature += subsidy;

View File

@@ -266,6 +266,36 @@ unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const
return nTxSize; return nTxSize;
} }
// will return the open time or block if this is a time locked transaction output that we recognize.
// if we can't determine that it has a valid time lock, it returns 0
int64_t CTransaction::UnlockTime(uint32_t voutNum) const
{
if (vout.size() > voutNum + 1 && vout[voutNum].scriptPubKey.IsPayToScriptHash())
{
uint32_t voutNext = voutNum + 1;
std::vector<uint8_t> opretData;
uint160 scriptID = uint160(std::vector<unsigned char>(vout[voutNum].scriptPubKey.begin() + 2, vout[voutNum].scriptPubKey.begin() + 22));
CScript::const_iterator it = vout[voutNext].scriptPubKey.begin() + 1;
opcodetype op;
if (vout[voutNext].scriptPubKey.GetOp2(it, op, &opretData))
{
if (opretData.size() > 0 && opretData.data()[0] == OPRETTYPE_TIMELOCK)
{
int64_t unlocktime;
CScript opretScript = CScript(opretData.begin() + 1, opretData.end());
if (Hash160(opretScript) == scriptID &&
opretScript.IsCheckLockTimeVerify(&unlocktime))
{
return(unlocktime);
}
}
}
}
return(0);
}
std::string CTransaction::ToString() const std::string CTransaction::ToString() const
{ {
std::string str; std::string str;

View File

@@ -457,6 +457,8 @@ public:
return (vin.size() == 1 && vin[0].prevout.IsNull()); return (vin.size() == 1 && vin[0].prevout.IsNull());
} }
int64_t UnlockTime(uint32_t voutNum) const;
friend bool operator==(const CTransaction& a, const CTransaction& b) friend bool operator==(const CTransaction& a, const CTransaction& b)
{ {
return a.hash == b.hash; return a.hash == b.hash;

View File

@@ -267,8 +267,8 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
if ( ASSETCHAINS_SYMBOL[0] == 0 ) if ( ASSETCHAINS_SYMBOL[0] == 0 )
COINBASE_MATURITY = _COINBASE_MATURITY; COINBASE_MATURITY = _COINBASE_MATURITY;
quint32 numBlocksToMaturity = COINBASE_MATURITY + 1; quint32 numBlocksToMaturity = COINBASE_MATURITY + 1;
strHTML += "<br>" + tr("Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.").arg(QString::number(numBlocksToMaturity)) + "<br>"; strHTML += "<br>" + tr("Generated coins must mature %1 blocks and have any applicable time locks open before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.").arg(QString::number(numBlocksToMaturity)) + "<br>";
// we need to display any possible CLTV lock time // we need to display any possible CLTV lock time
} }

View File

@@ -284,6 +284,37 @@ bool CScript::IsPushOnly() const
return true; return true;
} }
// if the front of the script has check lock time verify. this is a fairly simple check.
// accepts NULL as parameter if unlockTime is not needed.
bool CScript::IsCheckLockTimeVerify(int64_t *unlockTime) const
{
opcodetype op;
std::vector<unsigned char> unlockTimeParam = std::vector<unsigned char>();
CScript::const_iterator it = this->begin();
if (this->GetOp2(it, op, &unlockTimeParam))
{
if (unlockTimeParam.size() >= 0 && unlockTimeParam.size() < 6 &&
*(this->data() + unlockTimeParam.size() + 1) == OP_CHECKLOCKTIMEVERIFY)
{
int i = unlockTimeParam.size() - 1;
for (*unlockTime = 0; i >= 0; i--)
{
*unlockTime <<= 8;
*unlockTime |= *((unsigned char *)unlockTimeParam.data() + i);
}
return true;
}
}
return false;
}
bool CScript::IsCheckLockTimeVerify() const
{
int64_t ult;
return this->IsCheckLockTimeVerify(&ult);
}
std::string CScript::ToString() const std::string CScript::ToString() const
{ {
std::string str; std::string str;

View File

@@ -17,6 +17,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
#define OPRETTYPE_TIMELOCK 1
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
// Max size of pushdata in a CC sig in bytes // Max size of pushdata in a CC sig in bytes
@@ -575,6 +577,13 @@ public:
/** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */ /** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */
bool IsPushOnly() const; bool IsPushOnly() const;
/** if the front of the script has check lock time verify. this is a fairly simple check.
* accepts NULL as parameter if unlockTime is not needed.
*/
bool IsCheckLockTimeVerify(int64_t *unlockTime) const;
bool IsCheckLockTimeVerify() const;
/** /**
* Returns whether the script is guaranteed to fail at execution, * Returns whether the script is guaranteed to fail at execution,
* regardless of the initial stack. This allows outputs to be pruned * regardless of the initial stack. This allows outputs to be pruned

View File

@@ -74,34 +74,3 @@ const CScriptExt &CScriptExt::TimeLockSpend(const CKeyID &key, int64_t unlocktim
return *this; return *this;
} }
// if the front of the script has check lock time verify. this is a fairly simple check.
// accepts NULL as parameter if unlockTime is not needed.
bool CScriptExt::IsCheckLockTimeVerify(int64_t *unlockTime) const
{
opcodetype op;
std::vector<unsigned char> unlockTimeParam = std::vector<unsigned char>();
CScript::const_iterator it = this->begin();
if (this->GetOp2(it, op, &unlockTimeParam))
{
if (unlockTimeParam.size() >= 0 && unlockTimeParam.size() < 6 &&
*(this->data() + unlockTimeParam.size() + 1) == OP_CHECKLOCKTIMEVERIFY)
{
int i = unlockTimeParam.size() - 1;
for (*unlockTime = 0; i >= 0; i--)
{
*unlockTime <<= 8;
*unlockTime |= *((unsigned char *)unlockTimeParam.data() + i);
}
return true;
}
}
return false;
}
bool CScriptExt::IsCheckLockTimeVerify() const
{
int64_t ult;
return this->IsCheckLockTimeVerify(&ult);
}

View File

@@ -11,8 +11,6 @@
#include "standard.h" #include "standard.h"
#include "pubkey.h" #include "pubkey.h"
#define OPRETTYPE_TIMELOCK 1
class CScriptExt : public CScript class CScriptExt : public CScript
{ {
public: public:
@@ -38,12 +36,6 @@ class CScriptExt : public CScript
// combined CLTV script and P2PKH // combined CLTV script and P2PKH
const CScriptExt &TimeLockSpend(const CKeyID &key, int64_t unlocktime) const; const CScriptExt &TimeLockSpend(const CKeyID &key, int64_t unlocktime) const;
// if the front of the script has check lock time verify. this is a fairly simple check.
// accepts NULL as parameter if unlockTime is not needed.
bool IsCheckLockTimeVerify(int64_t *unlockTime) const;
bool IsCheckLockTimeVerify() const;
}; };
#endif #endif

View File

@@ -312,6 +312,9 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem
} }
} }
extern int64_t ASSETCHAINS_TIMELOCKGTE;
int64_t komodo_block_unlocktime(uint32_t nHeight);
void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags) void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags)
{ {
// Remove transactions spending a coinbase which are now immature // Remove transactions spending a coinbase which are now immature
@@ -331,8 +334,10 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem
if (it2 != mapTx.end()) if (it2 != mapTx.end())
continue; continue;
const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
if (nCheckFrequency != 0) assert(coins); if (nCheckFrequency != 0) assert(coins);
if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) { if (!coins || (coins->IsCoinBase() && (((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY) &&
((signed long)nMemPoolHeight < komodo_block_unlocktime(coins->nHeight) &&
coins->IsAvailable(0) && coins->vout[0].nValue >= ASSETCHAINS_TIMELOCKGTE))) {
transactionsToRemove.push_back(tx); transactionsToRemove.push_back(tx);
break; break;
} }

Binary file not shown.

View File

@@ -17,6 +17,7 @@ uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC; uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC;
uint32_t ASSETCHAINS_MAGIC = 2387029918; uint32_t ASSETCHAINS_MAGIC = 2387029918;
uint32_t ASSETCHAINS_EQUIHASH = 0; uint32_t ASSETCHAINS_EQUIHASH = 0;
uint32_t ASSETCHAINS_VERUSHASH = 1;
uint32_t ASSETCHAINS_ALGO = 0; uint32_t ASSETCHAINS_ALGO = 0;
unsigned int MAX_BLOCK_SIGOPS = 20000; unsigned int MAX_BLOCK_SIGOPS = 20000;

View File

@@ -1206,7 +1206,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
bool fExisted = mapWallet.count(tx.GetHash()) != 0; bool fExisted = mapWallet.count(tx.GetHash()) != 0;
if (fExisted && !fUpdate) return false; if (fExisted && !fUpdate) return false;
auto noteData = FindMyNotes(tx); auto noteData = FindMyNotes(tx);
if (fExisted || IsMineOrWatch(tx) || IsFromMe(tx) || noteData.size() > 0) if (fExisted || IsMine(tx) || IsFromMe(tx) || noteData.size() > 0)
{ {
CWalletTx wtx(this,tx); CWalletTx wtx(this,tx);
@@ -1468,49 +1468,18 @@ bool CWallet::IsMine(const CTransaction& tx)
return false; return false;
} }
bool CWallet::IsMineOrWatch(const CTransaction& tx)
{
for (int i = 0; i < tx.vout.size(); i++)
{
if (IsMine(tx, i) & ISMINE_ALL)
return true;
}
return false;
}
// special case handling for CLTV scripts, this does not error check to ensure the script is CLTV and is // special case handling for CLTV scripts, this does not error check to ensure the script is CLTV and is
// only internal to the wallet for that reason. if it is the first time we see this script, we add it to the wallet. // only internal to the wallet for that reason.
isminetype CWallet::IsCLTVMine(CScriptExt &script, CScriptID &scriptID, int64_t locktime) isminetype CWallet::IsCLTVMine(CScript &script, CScriptID &scriptID, int64_t locktime) const
{ {
uint8_t pushOp = script.data()[0]; uint8_t pushOp = script.data()[0];
uint32_t scriptStart = pushOp + 3; uint32_t scriptStart = pushOp + 3;
// check post CLTV script // check post CLTV script
CScriptExt postfix = CScriptExt(script.size() > scriptStart ? script.begin() + scriptStart : script.end(), script.end()); CScript postfix = CScript(script.size() > scriptStart ? script.begin() + scriptStart : script.end(), script.end());
// check again with postfix subscript // check again with postfix subscript
isminetype ret = ::IsMine(*this, postfix); return(::IsMine(*this, postfix));
if (ret == ISMINE_SPENDABLE)
{
// once we get here, we should have this script in our
// wallet, either as watch only if still time locked, or spendable
CBlockIndex &tip = *(chainActive.Tip());
if (!(locktime < LOCKTIME_THRESHOLD ? tip.nHeight >= locktime : tip.GetBlockTime() >= locktime))
{
ret = ISMINE_WATCH_ONLY;
if (!this->HaveWatchOnly(script))
{
this->AddWatchOnly(script);
}
} else
{
if (this->HaveWatchOnly(script))
this->RemoveWatchOnly(script);
if (!this->HaveCScript(scriptID))
this->AddCScript(script);
}
}
return ret;
} }
typedef vector<unsigned char> valtype; typedef vector<unsigned char> valtype;
@@ -1584,7 +1553,7 @@ isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum)
if (opretData.size() > 0 && opretData.data()[0] == OPRETTYPE_TIMELOCK) if (opretData.size() > 0 && opretData.data()[0] == OPRETTYPE_TIMELOCK)
{ {
int64_t unlocktime; int64_t unlocktime;
CScriptExt opretScript = CScriptExt(opretData.begin() + 1, opretData.end()); CScript opretScript = CScriptExt(opretData.begin() + 1, opretData.end());
if (CScriptID(opretScript) == scriptID && if (CScriptID(opretScript) == scriptID &&
opretScript.IsCheckLockTimeVerify(&unlocktime)) opretScript.IsCheckLockTimeVerify(&unlocktime))
@@ -3952,10 +3921,12 @@ int CMerkleTx::GetBlocksToMaturity() const
COINBASE_MATURITY = _COINBASE_MATURITY; COINBASE_MATURITY = _COINBASE_MATURITY;
if (!IsCoinBase()) if (!IsCoinBase())
return 0; return 0;
return max(0, (COINBASE_MATURITY+1) - GetDepthInMainChain()); uint32_t depth = GetDepthInMainChain();
uint32_t ui;
uint32_t toMaturity = (ui = UnlockTime(0) - chainActive.Height()) < 0 ? 0 : ui;
return((ui = COINBASE_MATURITY - depth) < toMaturity ? toMaturity : ui);
} }
bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
{ {
CValidationState state; CValidationState state;

View File

@@ -277,7 +277,6 @@ struct CNotePlaintextEntry
}; };
/** A transaction with a merkle branch linking it to the block chain. */ /** A transaction with a merkle branch linking it to the block chain. */
class CMerkleTx : public CTransaction class CMerkleTx : public CTransaction
{ {
@@ -762,7 +761,7 @@ protected:
private: private:
template <class T> template <class T>
void SyncMetaData(std::pair<typename TxSpendMap<T>::iterator, typename TxSpendMap<T>::iterator>); void SyncMetaData(std::pair<typename TxSpendMap<T>::iterator, typename TxSpendMap<T>::iterator>);
isminetype IsCLTVMine(CScriptExt &script, CScriptID &scriptID, int64_t locktime); isminetype IsCLTVMine(CScript &script, CScriptID &scriptID, int64_t locktime) const;
protected: protected:
bool UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx); bool UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx);
@@ -904,14 +903,12 @@ public:
void UnlockAllCoins(); void UnlockAllCoins();
void ListLockedCoins(std::vector<COutPoint>& vOutpts); void ListLockedCoins(std::vector<COutPoint>& vOutpts);
bool IsLockedNote(uint256 hash, size_t js, uint8_t n) const; bool IsLockedNote(uint256 hash, size_t js, uint8_t n) const;
void LockNote(JSOutPoint& output); void LockNote(JSOutPoint& output);
void UnlockNote(JSOutPoint& output); void UnlockNote(JSOutPoint& output);
void UnlockAllNotes(); void UnlockAllNotes();
std::vector<JSOutPoint> ListLockedNotes(); std::vector<JSOutPoint> ListLockedNotes();
/** /**
* keystore implementation * keystore implementation
* Generate a new key * Generate a new key
@@ -1056,7 +1053,6 @@ public:
bool IsChange(const CTxOut& txout) const; bool IsChange(const CTxOut& txout) const;
CAmount GetChange(const CTxOut& txout) const; CAmount GetChange(const CTxOut& txout) const;
bool IsMine(const CTransaction& tx); bool IsMine(const CTransaction& tx);
bool IsMineOrWatch(const CTransaction& tx);
/** should probably be renamed to IsRelevantToMe */ /** should probably be renamed to IsRelevantToMe */
bool IsFromMe(const CTransaction& tx) const; bool IsFromMe(const CTransaction& tx) const;
CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const; CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const;