Merge pull request #1 from miketout/dev
pull latest komodo and miketout changes
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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 )
|
||||||
|
|||||||
@@ -2057,6 +2057,14 @@ namespace Consensus {
|
|||||||
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
|
||||||
if (fCoinbaseEnforcedProtectionEnabled &&
|
if (fCoinbaseEnforcedProtectionEnabled &&
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user