Fix a bug that treats all claims as our own wallet txs.

This commit is contained in:
lbrynaut 2019-05-22 13:30:03 -05:00 committed by Brannon King
parent 55f5f2049e
commit 70e7743acc
2 changed files with 29 additions and 12 deletions

View file

@ -7,6 +7,7 @@
#include <key.h> #include <key.h>
#include <keystore.h> #include <keystore.h>
#include <nameclaim.h>
#include <script/script.h> #include <script/script.h>
#include <script/sign.h> #include <script/sign.h>
@ -39,6 +40,8 @@ enum class IsMineResult
WATCH_ONLY = 1, //! Included in watch-only balance WATCH_ONLY = 1, //! Included in watch-only balance
SPENDABLE = 2, //! Included in all balances SPENDABLE = 2, //! Included in all balances
INVALID = 3, //! Not spendable by anyone (uncompressed pubkey in segwit, P2SH inside P2SH or witness, witness inside witness) INVALID = 3, //! Not spendable by anyone (uncompressed pubkey in segwit, P2SH inside P2SH or witness, witness inside witness)
CLAIM = 4,
SUPPORT = 5,
}; };
bool PermitsUncompressed(IsMineSigVersion sigversion) bool PermitsUncompressed(IsMineSigVersion sigversion)
@ -57,7 +60,15 @@ bool HaveKeys(const std::vector<valtype>& pubkeys, const CKeyStore& keystore)
IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion) IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion)
{ {
int op = 0;
IsMineResult ret = IsMineResult::NO; IsMineResult ret = IsMineResult::NO;
IsMineResult claim_ret = IsMineResult::NO;
CScript strippedScriptPubKey = StripClaimScriptPrefix(scriptPubKey, op);
if (strippedScriptPubKey != scriptPubKey)
claim_ret = ((op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM) ? IsMineResult::CLAIM :
((op == OP_SUPPORT_CLAIM) ? IsMineResult::SUPPORT :
IsMineResult::NO));
std::vector<valtype> vSolutions; std::vector<valtype> vSolutions;
txnouttype whichType; txnouttype whichType;
@ -76,7 +87,7 @@ IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey,
return IsMineResult::INVALID; return IsMineResult::INVALID;
} }
if (keystore.HaveKey(keyID)) { if (keystore.HaveKey(keyID)) {
ret = std::max(ret, IsMineResult::SPENDABLE); ret = std::max(claim_ret, IsMineResult::SPENDABLE);
} }
break; break;
case TX_WITNESS_V0_KEYHASH: case TX_WITNESS_V0_KEYHASH:
@ -91,6 +102,10 @@ IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey,
// This also applies to the P2WSH case. // This also applies to the P2WSH case.
break; break;
} }
// Claims are not explicitly supported on Witness v0
// Transactions, and instead of supporting the wrapped inner
// tx, we are ignoring this type at this time (consistent with
// previous releases).
ret = std::max(ret, IsMineInner(keystore, GetScriptForDestination(CKeyID(uint160(vSolutions[0]))), IsMineSigVersion::WITNESS_V0)); ret = std::max(ret, IsMineInner(keystore, GetScriptForDestination(CKeyID(uint160(vSolutions[0]))), IsMineSigVersion::WITNESS_V0));
break; break;
} }
@ -103,7 +118,7 @@ IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey,
} }
} }
if (keystore.HaveKey(keyID)) { if (keystore.HaveKey(keyID)) {
ret = std::max(ret, IsMineResult::SPENDABLE); ret = std::max(claim_ret, IsMineResult::SPENDABLE);
} }
break; break;
case TX_SCRIPTHASH: case TX_SCRIPTHASH:
@ -115,7 +130,7 @@ IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey,
CScriptID scriptID = CScriptID(uint160(vSolutions[0])); CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
CScript subscript; CScript subscript;
if (keystore.GetCScript(scriptID, subscript)) { if (keystore.GetCScript(scriptID, subscript)) {
ret = std::max(ret, IsMineInner(keystore, subscript, IsMineSigVersion::P2SH)); ret = std::max(claim_ret, IsMineInner(keystore, subscript, IsMineSigVersion::P2SH));
} }
break; break;
} }
@ -133,6 +148,10 @@ IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey,
CScriptID scriptID = CScriptID(hash); CScriptID scriptID = CScriptID(hash);
CScript subscript; CScript subscript;
if (keystore.GetCScript(scriptID, subscript)) { if (keystore.GetCScript(scriptID, subscript)) {
// Claims are not explicitly supported on Witness v0
// Transactions, and instead of supporting the wrapped inner
// tx, we are ignoring this type at this time (consistent with
// previous releases).
ret = std::max(ret, IsMineInner(keystore, subscript, IsMineSigVersion::WITNESS_V0)); ret = std::max(ret, IsMineInner(keystore, subscript, IsMineSigVersion::WITNESS_V0));
} }
break; break;
@ -159,14 +178,14 @@ IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey,
} }
} }
if (HaveKeys(keys, keystore)) { if (HaveKeys(keys, keystore)) {
ret = std::max(ret, IsMineResult::SPENDABLE); ret = std::max(claim_ret, IsMineResult::SPENDABLE);
} }
break; break;
} }
} }
if (ret == IsMineResult::NO && keystore.HaveWatchOnly(scriptPubKey)) { if (ret == IsMineResult::NO && keystore.HaveWatchOnly(scriptPubKey)) {
ret = std::max(ret, IsMineResult::WATCH_ONLY); ret = std::max(claim_ret, IsMineResult::WATCH_ONLY);
} }
return ret; return ret;
} }
@ -183,6 +202,10 @@ isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey)
return ISMINE_WATCH_ONLY; return ISMINE_WATCH_ONLY;
case IsMineResult::SPENDABLE: case IsMineResult::SPENDABLE:
return ISMINE_SPENDABLE; return ISMINE_SPENDABLE;
case IsMineResult::CLAIM:
return ISMINE_CLAIM;
case IsMineResult::SUPPORT:
return ISMINE_SUPPORT;
} }
assert(false); assert(false);
} }

View file

@ -1382,13 +1382,7 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
isminetype CWallet::IsMine(const CTxOut& txout) const isminetype CWallet::IsMine(const CTxOut& txout) const
{ {
int op = 0; return ::IsMine(*this, txout.scriptPubKey);
auto script = StripClaimScriptPrefix(txout.scriptPubKey, op);
if (op == OP_CLAIM_NAME)
return isminetype::ISMINE_CLAIM;
if (op == OP_SUPPORT_CLAIM)
return isminetype::ISMINE_SUPPORT;
return ::IsMine(*this, script);
} }
CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const