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_ALGO;
|
||||
extern uint64_t ASSETCHAINS_EQUIHASH;
|
||||
extern uint64_t ASSETCHAINS_VERUSHASH;
|
||||
|
||||
const arith_uint256 maxUint = UintToArith256(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
|
||||
|
||||
@@ -100,7 +101,10 @@ public:
|
||||
consensus.nMajorityEnforceBlockUpgrade = 750;
|
||||
consensus.nMajorityRejectBlockOutdated = 950;
|
||||
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.nMaxFutureBlockTime = 7 * 60; // 7 mins
|
||||
|
||||
@@ -182,7 +186,7 @@ public:
|
||||
|
||||
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
|
||||
|
||||
//fMiningRequiresPeers = true;
|
||||
fMiningRequiresPeers = true;
|
||||
fDefaultConsistencyChecks = false;
|
||||
fRequireStandard = true;
|
||||
fMineBlocksOnDemand = false;
|
||||
|
||||
@@ -117,14 +117,14 @@ int64_t komodo_current_supply(uint32_t nHeight)
|
||||
int32_t baseid;
|
||||
|
||||
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
|
||||
{
|
||||
// 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;
|
||||
if ( ASSETCHAINS_LASTERA == 0 && ASSETCHAINS_REWARD[0] == 0 )
|
||||
{
|
||||
cur_money = ASSETCHAINS_SUPPLY + (nHeight * 10000) / SATOSHIDEN;
|
||||
cur_money += (nHeight * 10000) / SATOSHIDEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -80,13 +80,15 @@ uint64_t komodo_moneysupply(int32_t height)
|
||||
}
|
||||
#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;
|
||||
if ( nLockTime >= LOCKTIME_THRESHOLD && tiptime > nLockTime && (minutes= (tiptime - nLockTime) / 60) >= 60 )
|
||||
{
|
||||
if ( minutes > 365 * 24 * 60 )
|
||||
minutes = 365 * 24 * 60;
|
||||
if ( txheight >= 1000000 && minutes > 31 * 24 * 60 )
|
||||
minutes = 31 * 24 * 60;
|
||||
minutes -= 59;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -151,21 +153,21 @@ uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uin
|
||||
else if ( txheight < 1000000 )
|
||||
{
|
||||
interest = (numerator * minutes) / ((uint64_t)365 * 24 * 60);
|
||||
interestnew = _komodo_interestnew(nValue,nLockTime,tiptime);
|
||||
interestnew = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
|
||||
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);
|
||||
}
|
||||
else interest = _komodo_interestnew(nValue,nLockTime,tiptime);
|
||||
else interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
|
||||
}
|
||||
else if ( txheight < 1000000 )
|
||||
{
|
||||
numerator = (nValue * KOMODO_INTEREST);
|
||||
interest = (numerator / denominator) / COIN;
|
||||
interestnew = _komodo_interestnew(nValue,nLockTime,tiptime);
|
||||
interestnew = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
|
||||
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);
|
||||
}
|
||||
else interest = _komodo_interestnew(nValue,nLockTime,tiptime);
|
||||
else interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -187,11 +189,11 @@ uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uin
|
||||
numerator = (nValue / 20); // assumes 5%!
|
||||
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);
|
||||
interestnew = _komodo_interestnew(nValue,nLockTime,tiptime);
|
||||
interestnew = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
|
||||
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);
|
||||
}
|
||||
else interest = _komodo_interestnew(nValue,nLockTime,tiptime);
|
||||
else interest = _komodo_interestnew(txheight,nValue,nLockTime,tiptime);
|
||||
}
|
||||
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));
|
||||
|
||||
@@ -1733,6 +1733,11 @@ void komodo_args(char *argv0)
|
||||
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
|
||||
// param was specified, otherwise, for compatibility, do nothing
|
||||
if ( ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF )
|
||||
@@ -1777,7 +1782,8 @@ void komodo_args(char *argv0)
|
||||
if ( (port= komodo_userpass(ASSETCHAINS_USERPASS,ASSETCHAINS_SYMBOL)) != 0 )
|
||||
ASSETCHAINS_RPCPORT = port;
|
||||
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);
|
||||
}
|
||||
if ( ASSETCHAINS_RPCPORT == 0 )
|
||||
|
||||
@@ -2056,6 +2056,14 @@ namespace Consensus {
|
||||
error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
|
||||
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
|
||||
// Disabled on regtest
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
extern int64_t ASSETCHAINS_TIMELOCKGTE;
|
||||
int64_t komodo_block_unlocktime(uint32_t nHeight);
|
||||
|
||||
void AtomicTimer::start()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
@@ -335,7 +338,9 @@ int printMetrics(size_t cols, bool mining)
|
||||
if ((height > 0) && (height <= consensusParams.GetLastFoundersRewardBlockHeight())) {
|
||||
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;
|
||||
} else {
|
||||
mature += subsidy;
|
||||
|
||||
@@ -266,6 +266,36 @@ unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const
|
||||
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 str;
|
||||
|
||||
@@ -457,6 +457,8 @@ public:
|
||||
return (vin.size() == 1 && vin[0].prevout.IsNull());
|
||||
}
|
||||
|
||||
int64_t UnlockTime(uint32_t voutNum) const;
|
||||
|
||||
friend bool operator==(const CTransaction& a, const CTransaction& b)
|
||||
{
|
||||
return a.hash == b.hash;
|
||||
|
||||
@@ -267,8 +267,8 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
|
||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
if ( ASSETCHAINS_SYMBOL[0] == 0 )
|
||||
COINBASE_MATURITY = _COINBASE_MATURITY;
|
||||
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>";
|
||||
quint32 numBlocksToMaturity = COINBASE_MATURITY + 1;
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -284,6 +284,37 @@ bool CScript::IsPushOnly() const
|
||||
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 str;
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define OPRETTYPE_TIMELOCK 1
|
||||
|
||||
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // 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). */
|
||||
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,
|
||||
* 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;
|
||||
}
|
||||
|
||||
// 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 "pubkey.h"
|
||||
|
||||
#define OPRETTYPE_TIMELOCK 1
|
||||
|
||||
class CScriptExt : public CScript
|
||||
{
|
||||
public:
|
||||
@@ -38,12 +36,6 @@ class CScriptExt : public CScript
|
||||
|
||||
// combined CLTV script and P2PKH
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
// 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())
|
||||
continue;
|
||||
const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
|
||||
if (nCheckFrequency != 0) assert(coins);
|
||||
if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) {
|
||||
if (nCheckFrequency != 0) assert(coins);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -17,6 +17,7 @@ uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
|
||||
uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC;
|
||||
uint32_t ASSETCHAINS_MAGIC = 2387029918;
|
||||
uint32_t ASSETCHAINS_EQUIHASH = 0;
|
||||
uint32_t ASSETCHAINS_VERUSHASH = 1;
|
||||
uint32_t ASSETCHAINS_ALGO = 0;
|
||||
|
||||
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;
|
||||
if (fExisted && !fUpdate) return false;
|
||||
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);
|
||||
|
||||
@@ -1468,49 +1468,18 @@ bool CWallet::IsMine(const CTransaction& tx)
|
||||
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
|
||||
// only internal to the wallet for that reason. if it is the first time we see this script, we add it to the wallet.
|
||||
isminetype CWallet::IsCLTVMine(CScriptExt &script, CScriptID &scriptID, int64_t locktime)
|
||||
// only internal to the wallet for that reason.
|
||||
isminetype CWallet::IsCLTVMine(CScript &script, CScriptID &scriptID, int64_t locktime) const
|
||||
{
|
||||
uint8_t pushOp = script.data()[0];
|
||||
uint32_t scriptStart = pushOp + 3;
|
||||
|
||||
// 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
|
||||
isminetype ret = ::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;
|
||||
return(::IsMine(*this, postfix));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int64_t unlocktime;
|
||||
CScriptExt opretScript = CScriptExt(opretData.begin() + 1, opretData.end());
|
||||
CScript opretScript = CScriptExt(opretData.begin() + 1, opretData.end());
|
||||
|
||||
if (CScriptID(opretScript) == scriptID &&
|
||||
opretScript.IsCheckLockTimeVerify(&unlocktime))
|
||||
@@ -3952,10 +3921,12 @@ int CMerkleTx::GetBlocksToMaturity() const
|
||||
COINBASE_MATURITY = _COINBASE_MATURITY;
|
||||
if (!IsCoinBase())
|
||||
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)
|
||||
{
|
||||
CValidationState state;
|
||||
|
||||
@@ -277,7 +277,6 @@ struct CNotePlaintextEntry
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** A transaction with a merkle branch linking it to the block chain. */
|
||||
class CMerkleTx : public CTransaction
|
||||
{
|
||||
@@ -762,7 +761,7 @@ protected:
|
||||
private:
|
||||
template <class T>
|
||||
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:
|
||||
bool UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx);
|
||||
@@ -904,14 +903,12 @@ public:
|
||||
void UnlockAllCoins();
|
||||
void ListLockedCoins(std::vector<COutPoint>& vOutpts);
|
||||
|
||||
|
||||
bool IsLockedNote(uint256 hash, size_t js, uint8_t n) const;
|
||||
void LockNote(JSOutPoint& output);
|
||||
void UnlockNote(JSOutPoint& output);
|
||||
void UnlockAllNotes();
|
||||
std::vector<JSOutPoint> ListLockedNotes();
|
||||
|
||||
|
||||
/**
|
||||
* keystore implementation
|
||||
* Generate a new key
|
||||
@@ -1056,7 +1053,6 @@ public:
|
||||
bool IsChange(const CTxOut& txout) const;
|
||||
CAmount GetChange(const CTxOut& txout) const;
|
||||
bool IsMine(const CTransaction& tx);
|
||||
bool IsMineOrWatch(const CTransaction& tx);
|
||||
/** should probably be renamed to IsRelevantToMe */
|
||||
bool IsFromMe(const CTransaction& tx) const;
|
||||
CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const;
|
||||
|
||||
Reference in New Issue
Block a user