Merge pull request #13 from miketout/dev
Recognizing CLTV transactions more broadly
This commit is contained in:
@@ -226,6 +226,20 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
||||
{
|
||||
vector<valtype> vSolutions;
|
||||
txnouttype whichType;
|
||||
|
||||
// if this is a CLTV script, get the destination after CLTV
|
||||
if (scriptPubKey.IsCheckLockTimeVerify())
|
||||
{
|
||||
uint8_t pushOp = scriptPubKey.data()[0];
|
||||
uint32_t scriptStart = pushOp + 3;
|
||||
|
||||
// check post CLTV script
|
||||
CScript postfix = CScript(scriptPubKey.size() > scriptStart ? scriptPubKey.begin() + scriptStart : scriptPubKey.end(), scriptPubKey.end());
|
||||
|
||||
// check again with only postfix subscript
|
||||
return(ExtractDestination(postfix, addressRet));
|
||||
}
|
||||
|
||||
if (!Solver(scriptPubKey, whichType, vSolutions))
|
||||
return false;
|
||||
|
||||
@@ -260,6 +274,20 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto
|
||||
addressRet.clear();
|
||||
typeRet = TX_NONSTANDARD;
|
||||
vector<valtype> vSolutions;
|
||||
|
||||
// if this is a CLTV script, get the destinations after CLTV
|
||||
if (scriptPubKey.IsCheckLockTimeVerify())
|
||||
{
|
||||
uint8_t pushOp = scriptPubKey.data()[0];
|
||||
uint32_t scriptStart = pushOp + 3;
|
||||
|
||||
// check post CLTV script
|
||||
CScript postfix = CScript(scriptPubKey.size() > scriptStart ? scriptPubKey.begin() + scriptStart : scriptPubKey.end(), scriptPubKey.end());
|
||||
|
||||
// check again with only postfix subscript
|
||||
return(ExtractDestinations(postfix, typeRet, addressRet, nRequiredRet));
|
||||
}
|
||||
|
||||
if (!Solver(scriptPubKey, typeRet, vSolutions))
|
||||
return false;
|
||||
if (typeRet == TX_NULL_DATA){
|
||||
|
||||
@@ -1395,7 +1395,7 @@ isminetype CWallet::IsMine(const CTxIn &txin) const
|
||||
{
|
||||
const CWalletTx& prev = (*mi).second;
|
||||
if (txin.prevout.n < prev.vout.size())
|
||||
return IsMine(prev, txin.prevout.n);
|
||||
return (::IsMine(*this, prev.vout[txin.prevout.n].scriptPubKey));
|
||||
}
|
||||
}
|
||||
return ISMINE_NO;
|
||||
@@ -1410,7 +1410,7 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
|
||||
{
|
||||
const CWalletTx& prev = (*mi).second;
|
||||
if (txin.prevout.n < prev.vout.size())
|
||||
if (IsMine(prev, txin.prevout.n) & filter)
|
||||
if (::IsMine(*this, prev.vout[txin.prevout.n].scriptPubKey) & filter)
|
||||
return prev.vout[txin.prevout.n].nValue; // komodo_interest?
|
||||
}
|
||||
}
|
||||
@@ -1458,6 +1458,9 @@ CAmount CWallet::GetChange(const CTxOut& txout) const
|
||||
return (IsChange(txout) ? txout.nValue : 0);
|
||||
}
|
||||
|
||||
typedef vector<unsigned char> valtype;
|
||||
unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore);
|
||||
|
||||
bool CWallet::IsMine(const CTransaction& tx)
|
||||
{
|
||||
for (int i = 0; i < tx.vout.size(); i++)
|
||||
@@ -1468,26 +1471,9 @@ bool CWallet::IsMine(const CTransaction& tx)
|
||||
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.
|
||||
isminetype CWallet::IsCLTVMine(CScript &script, CScriptID &scriptID) const
|
||||
{
|
||||
uint8_t pushOp = script.data()[0];
|
||||
uint32_t scriptStart = pushOp + 3;
|
||||
|
||||
// check post CLTV script
|
||||
CScript postfix = CScript(script.size() > scriptStart ? script.begin() + scriptStart : script.end(), script.end());
|
||||
|
||||
// check again with postfix subscript
|
||||
return(::IsMine(*this, postfix));
|
||||
}
|
||||
|
||||
typedef vector<unsigned char> valtype;
|
||||
unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore);
|
||||
|
||||
// special case handling for non-standard/Verus OP_RETURN script outputs, which need the transaction
|
||||
// to determine ownership
|
||||
isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum) const
|
||||
isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum)
|
||||
{
|
||||
vector<valtype> vSolutions;
|
||||
txnouttype whichType;
|
||||
@@ -1529,7 +1515,7 @@ isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum) const
|
||||
// if this is a CLTV, handle it differently
|
||||
if (subscript.IsCheckLockTimeVerify())
|
||||
{
|
||||
return this->IsCLTVMine(subscript, scriptID);
|
||||
return (::IsMine(*this, subscript));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1556,7 +1542,14 @@ isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum) const
|
||||
if (CScriptID(opretScript) == scriptID &&
|
||||
opretScript.IsCheckLockTimeVerify())
|
||||
{
|
||||
return this->IsCLTVMine(opretScript, scriptID);
|
||||
// if we find that this is ours, we need to add this script to the wallet,
|
||||
// and we can then recognize this transaction
|
||||
isminetype t = ::IsMine(*this, opretScript);
|
||||
if (t != ISMINE_NO)
|
||||
{
|
||||
this->AddCScript(opretScript);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1612,7 +1605,7 @@ CAmount CWallet::GetCredit(const CTransaction& tx, int32_t voutNum, const ismine
|
||||
{
|
||||
if (voutNum >= tx.vout.size() || !MoneyRange(tx.vout[voutNum].nValue))
|
||||
throw std::runtime_error("CWallet::GetCredit(): value out of range");
|
||||
return ((IsMine(tx, voutNum) & filter) ? tx.vout[voutNum].nValue : 0);
|
||||
return ((IsMine(tx.vout[voutNum]) & filter) ? tx.vout[voutNum].nValue : 0);
|
||||
}
|
||||
|
||||
CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const
|
||||
@@ -2397,7 +2390,7 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const
|
||||
|
||||
for (int i = 0; i < pcoin->vout.size(); i++)
|
||||
{
|
||||
isminetype mine = IsMine(*pcoin, i);
|
||||
isminetype mine = IsMine(pcoin->vout[i]);
|
||||
if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
|
||||
!IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) &&
|
||||
(!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
|
||||
|
||||
@@ -762,9 +762,6 @@ private:
|
||||
template <class T>
|
||||
void SyncMetaData(std::pair<typename TxSpendMap<T>::iterator, typename TxSpendMap<T>::iterator>);
|
||||
|
||||
// parses a CLTV script followed by a standard script and determines ownership
|
||||
isminetype IsCLTVMine(CScript &subScript, CScriptID &scriptID) const;
|
||||
|
||||
protected:
|
||||
bool UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx);
|
||||
void MarkAffectedTransactionsDirty(const CTransaction& tx);
|
||||
@@ -1050,7 +1047,7 @@ public:
|
||||
isminetype IsMine(const CTxIn& txin) const;
|
||||
CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const;
|
||||
isminetype IsMine(const CTxOut& txout) const;
|
||||
isminetype IsMine(const CTransaction& tx, uint32_t voutNum) const;
|
||||
isminetype IsMine(const CTransaction& tx, uint32_t voutNum);
|
||||
CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const;
|
||||
bool IsChange(const CTxOut& txout) const;
|
||||
CAmount GetChange(const CTxOut& txout) const;
|
||||
|
||||
@@ -34,10 +34,21 @@ isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest)
|
||||
return IsMine(keystore, script);
|
||||
}
|
||||
|
||||
isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||
isminetype IsMine(const CKeyStore &keystore, const CScript& _scriptPubKey)
|
||||
{
|
||||
vector<valtype> vSolutions;
|
||||
txnouttype whichType;
|
||||
CScript scriptPubKey = _scriptPubKey;
|
||||
|
||||
if (scriptPubKey.IsCheckLockTimeVerify())
|
||||
{
|
||||
uint8_t pushOp = scriptPubKey.data()[0];
|
||||
uint32_t scriptStart = pushOp + 3;
|
||||
|
||||
// continue with post CLTV script
|
||||
scriptPubKey = CScript(scriptPubKey.size() > scriptStart ? scriptPubKey.begin() + scriptStart : scriptPubKey.end(), scriptPubKey.end());
|
||||
}
|
||||
|
||||
if (!Solver(scriptPubKey, whichType, vSolutions)) {
|
||||
if (keystore.HaveWatchOnly(scriptPubKey))
|
||||
return ISMINE_WATCH_ONLY;
|
||||
|
||||
Reference in New Issue
Block a user