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;
|
vector<valtype> vSolutions;
|
||||||
txnouttype whichType;
|
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))
|
if (!Solver(scriptPubKey, whichType, vSolutions))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -260,6 +274,20 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto
|
|||||||
addressRet.clear();
|
addressRet.clear();
|
||||||
typeRet = TX_NONSTANDARD;
|
typeRet = TX_NONSTANDARD;
|
||||||
vector<valtype> vSolutions;
|
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))
|
if (!Solver(scriptPubKey, typeRet, vSolutions))
|
||||||
return false;
|
return false;
|
||||||
if (typeRet == TX_NULL_DATA){
|
if (typeRet == TX_NULL_DATA){
|
||||||
|
|||||||
@@ -1395,7 +1395,7 @@ isminetype CWallet::IsMine(const CTxIn &txin) const
|
|||||||
{
|
{
|
||||||
const CWalletTx& prev = (*mi).second;
|
const CWalletTx& prev = (*mi).second;
|
||||||
if (txin.prevout.n < prev.vout.size())
|
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;
|
return ISMINE_NO;
|
||||||
@@ -1410,7 +1410,7 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
|
|||||||
{
|
{
|
||||||
const CWalletTx& prev = (*mi).second;
|
const CWalletTx& prev = (*mi).second;
|
||||||
if (txin.prevout.n < prev.vout.size())
|
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?
|
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);
|
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)
|
bool CWallet::IsMine(const CTransaction& tx)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < tx.vout.size(); i++)
|
for (int i = 0; i < tx.vout.size(); i++)
|
||||||
@@ -1468,26 +1471,9 @@ bool CWallet::IsMine(const CTransaction& tx)
|
|||||||
return false;
|
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
|
// special case handling for non-standard/Verus OP_RETURN script outputs, which need the transaction
|
||||||
// to determine ownership
|
// 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;
|
vector<valtype> vSolutions;
|
||||||
txnouttype whichType;
|
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 this is a CLTV, handle it differently
|
||||||
if (subscript.IsCheckLockTimeVerify())
|
if (subscript.IsCheckLockTimeVerify())
|
||||||
{
|
{
|
||||||
return this->IsCLTVMine(subscript, scriptID);
|
return (::IsMine(*this, subscript));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1556,7 +1542,14 @@ isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum) const
|
|||||||
if (CScriptID(opretScript) == scriptID &&
|
if (CScriptID(opretScript) == scriptID &&
|
||||||
opretScript.IsCheckLockTimeVerify())
|
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))
|
if (voutNum >= tx.vout.size() || !MoneyRange(tx.vout[voutNum].nValue))
|
||||||
throw std::runtime_error("CWallet::GetCredit(): value out of range");
|
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
|
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++)
|
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 &&
|
if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
|
||||||
!IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) &&
|
!IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) &&
|
||||||
(!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
|
(!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
|
||||||
|
|||||||
@@ -762,9 +762,6 @@ 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>);
|
||||||
|
|
||||||
// parses a CLTV script followed by a standard script and determines ownership
|
|
||||||
isminetype IsCLTVMine(CScript &subScript, CScriptID &scriptID) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx);
|
bool UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx);
|
||||||
void MarkAffectedTransactionsDirty(const CTransaction& tx);
|
void MarkAffectedTransactionsDirty(const CTransaction& tx);
|
||||||
@@ -1050,7 +1047,7 @@ public:
|
|||||||
isminetype IsMine(const CTxIn& txin) const;
|
isminetype IsMine(const CTxIn& txin) const;
|
||||||
CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const;
|
CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const;
|
||||||
isminetype IsMine(const CTxOut& txout) 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;
|
CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const;
|
||||||
bool IsChange(const CTxOut& txout) const;
|
bool IsChange(const CTxOut& txout) const;
|
||||||
CAmount GetChange(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);
|
return IsMine(keystore, script);
|
||||||
}
|
}
|
||||||
|
|
||||||
isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
isminetype IsMine(const CKeyStore &keystore, const CScript& _scriptPubKey)
|
||||||
{
|
{
|
||||||
vector<valtype> vSolutions;
|
vector<valtype> vSolutions;
|
||||||
txnouttype whichType;
|
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 (!Solver(scriptPubKey, whichType, vSolutions)) {
|
||||||
if (keystore.HaveWatchOnly(scriptPubKey))
|
if (keystore.HaveWatchOnly(scriptPubKey))
|
||||||
return ISMINE_WATCH_ONLY;
|
return ISMINE_WATCH_ONLY;
|
||||||
|
|||||||
Reference in New Issue
Block a user