optimizing the wallet to better handle claimname calls
This commit is contained in:
parent
24fedd6f14
commit
18e4372eb9
5 changed files with 87 additions and 25 deletions
|
@ -119,10 +119,57 @@ bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector<std::vector
|
|||
vvchParams.push_back(std::move(vchParam2));
|
||||
if (last_drop == OP_2DROP)
|
||||
vvchParams.push_back(std::move(vchParam3));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// this overload exists because optimizer wouldn't inline GetScriptOp:
|
||||
bool DecodeClaimScript(const CScript& scriptIn, int& op, CScript::const_iterator& pc, bool allowSupportMetadata)
|
||||
{
|
||||
op = -1;
|
||||
opcodetype opcode;
|
||||
if (!scriptIn.GetOp(pc, opcode))
|
||||
return false;
|
||||
|
||||
if (opcode != OP_CLAIM_NAME && opcode != OP_SUPPORT_CLAIM && opcode != OP_UPDATE_CLAIM)
|
||||
return false;
|
||||
|
||||
op = opcode;
|
||||
|
||||
// Valid formats:
|
||||
// OP_CLAIM_NAME vchName vchValue OP_2DROP OP_DROP pubkeyscript
|
||||
// OP_UPDATE_CLAIM vchName vchClaimId vchValue OP_2DROP OP_2DROP pubkeyscript
|
||||
// OP_SUPPORT_CLAIM vchName vchClaimId OP_2DROP OP_DROP pubkeyscript
|
||||
// OP_SUPPORT_CLAIM vchName vchClaimId vchValue OP_2DROP OP_2DROP pubkeyscript
|
||||
// All others are invalid.
|
||||
|
||||
if (!scriptIn.GetOp(pc, opcode) || opcode < 0 || opcode > OP_PUSHDATA4)
|
||||
return false;
|
||||
|
||||
if (!scriptIn.GetOp(pc, opcode) || opcode < 0 || opcode > OP_PUSHDATA4)
|
||||
return false;
|
||||
|
||||
if (!scriptIn.GetOp(pc, opcode))
|
||||
return false;
|
||||
|
||||
auto last_drop = OP_DROP;
|
||||
if (opcode >= 0 && opcode <= OP_PUSHDATA4 && op != OP_CLAIM_NAME) {
|
||||
if (!scriptIn.GetOp(pc, opcode))
|
||||
return false;
|
||||
last_drop = OP_2DROP;
|
||||
} else if (op == OP_UPDATE_CLAIM)
|
||||
return false;
|
||||
|
||||
if (opcode != OP_2DROP)
|
||||
return false;
|
||||
|
||||
if (!scriptIn.GetOp(pc, opcode) || opcode != last_drop)
|
||||
return false;
|
||||
|
||||
return !(op == OP_SUPPORT_CLAIM && last_drop == OP_2DROP && !allowSupportMetadata);
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint160 ClaimIdHash(const uint256& txhash, uint32_t nOut)
|
||||
{
|
||||
std::vector<unsigned char> claimToHash(txhash.begin(), txhash.end());
|
||||
|
@ -139,10 +186,10 @@ CScript StripClaimScriptPrefix(const CScript& scriptIn)
|
|||
|
||||
CScript StripClaimScriptPrefix(const CScript& scriptIn, int& op)
|
||||
{
|
||||
std::vector<std::vector<unsigned char> > vvchParams;
|
||||
CScript::const_iterator pc = scriptIn.begin();
|
||||
|
||||
if (!DecodeClaimScript(scriptIn, op, vvchParams, pc))
|
||||
auto isClaim = DecodeClaimScript(scriptIn, op, pc);
|
||||
if (!isClaim)
|
||||
return scriptIn;
|
||||
|
||||
return CScript(pc, scriptIn.end());
|
||||
|
|
|
@ -30,6 +30,7 @@ CScript SupportClaimScript(std::string name, uint160 claimId, std::string value=
|
|||
CScript UpdateClaimScript(std::string name, uint160 claimId, std::string value);
|
||||
bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector<std::vector<unsigned char> >& vvchParams, bool allowSupportMetadata=true);
|
||||
bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector<std::vector<unsigned char> >& vvchParams, CScript::const_iterator& pc, bool allowSupportMetadata=true);
|
||||
bool DecodeClaimScript(const CScript& scriptIn, int& op, CScript::const_iterator& pc, bool allowSupportMetadata=true);
|
||||
CScript StripClaimScriptPrefix(const CScript& scriptIn);
|
||||
CScript StripClaimScriptPrefix(const CScript& scriptIn, int& op);
|
||||
uint160 ClaimIdHash(const uint256& txhash, uint32_t nOut);
|
||||
|
|
|
@ -3995,7 +3995,8 @@ static UniValue listunspent(const JSONRPCRequest& request)
|
|||
std::vector<COutput> vecOutputs;
|
||||
{
|
||||
LOCK2(cs_main, pwallet->cs_wallet);
|
||||
pwallet->AvailableCoins(vecOutputs, !include_unsafe, nullptr, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
|
||||
pwallet->AvailableCoins(vecOutputs, !include_unsafe, nullptr,
|
||||
nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth, true);
|
||||
}
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
|
|
@ -1877,7 +1877,8 @@ bool CWalletTx::RelayWalletTransaction(CConnman* connman)
|
|||
CValidationState state;
|
||||
/* GetDepthInMainChain already catches known conflicts. */
|
||||
if (InMempool() || AcceptToMemoryPool(maxTxFee, state)) {
|
||||
pwallet->WalletLogPrintf("Relaying wtx %s\n", GetHash().ToString());
|
||||
if (LogAcceptCategory(BCLog::DB))
|
||||
pwallet->WalletLogPrintf("Relaying wtx %s\n", GetHash().ToString());
|
||||
if (connman) {
|
||||
CInv inv(MSG_TX, GetHash());
|
||||
connman->ForEachNode([&inv](CNode* pnode)
|
||||
|
@ -2286,7 +2287,9 @@ CAmount CWallet::GetAvailableBalance(const CCoinControl* coinControl) const
|
|||
return balance;
|
||||
}
|
||||
|
||||
void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, const CCoinControl *coinControl, const CAmount &nMinimumAmount, const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount, const uint64_t nMaximumCount, const int nMinDepth, const int nMaxDepth) const
|
||||
void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, const CCoinControl *coinControl,
|
||||
const CAmount &nMinimumAmount, const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount,
|
||||
const uint64_t nMaximumCount, const int nMinDepth, const int nMaxDepth, bool computeSolvable) const
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
AssertLockHeld(cs_wallet);
|
||||
|
@ -2373,17 +2376,23 @@ void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, const
|
|||
continue;
|
||||
}
|
||||
|
||||
bool solvable = IsSolvable(*this, pcoin->tx->vout[i].scriptPubKey);
|
||||
bool spendable = (mine & ISMINE_SPENDABLE) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
|
||||
|
||||
// spending claims or supports requires specific selection:
|
||||
auto isClaimCoin = (mine & ISMINE_CLAIM) || (mine & ISMINE_SUPPORT);
|
||||
auto isClaimCoin = bool(mine & ISMINE_STAKE);
|
||||
auto claimSpendRequested = isClaimCoin && coinControl && coinControl->IsSelected(COutPoint(entry.first, i));
|
||||
|
||||
if (spendable && isClaimCoin && !claimSpendRequested)
|
||||
if (isClaimCoin && !claimSpendRequested)
|
||||
continue;
|
||||
|
||||
vCoins.push_back(COutput(pcoin, i, nDepth, spendable, solvable, safeTx, (coinControl && coinControl->fAllowWatchOnly)));
|
||||
bool solvable = false, computedSolvable = false;
|
||||
bool spendable = bool(mine & ISMINE_SPENDABLE);
|
||||
if (!spendable && bool(mine & ISMINE_WATCH_ONLY) && coinControl && coinControl->fAllowWatchOnly) {
|
||||
solvable = IsSolvable(*this, pcoin->tx->vout[i].scriptPubKey); // this is a slow call
|
||||
spendable = solvable;
|
||||
computedSolvable = true;
|
||||
};
|
||||
if (computeSolvable && !computedSolvable)
|
||||
solvable = IsSolvable(*this, pcoin->tx->vout[i].scriptPubKey);
|
||||
|
||||
vCoins.emplace_back(pcoin, i, nDepth, spendable, solvable, safeTx, (coinControl && coinControl->fAllowWatchOnly));
|
||||
|
||||
// Checks the sum amount of all UTXO's.
|
||||
if (nMinimumSumAmount != MAX_MONEY) {
|
||||
|
@ -3495,7 +3504,8 @@ bool CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRe
|
|||
}
|
||||
|
||||
m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
|
||||
WalletLogPrintf("keypool reserve %d\n", nIndex);
|
||||
if (LogAcceptCategory(BCLog::DB))
|
||||
WalletLogPrintf("keypool reserve %d\n", nIndex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -3505,7 +3515,8 @@ void CWallet::KeepKey(int64_t nIndex)
|
|||
// Remove from key pool
|
||||
WalletBatch batch(*database);
|
||||
batch.ErasePool(nIndex);
|
||||
WalletLogPrintf("keypool keep %d\n", nIndex);
|
||||
if (LogAcceptCategory(BCLog::DB))
|
||||
WalletLogPrintf("keypool keep %d\n", nIndex);
|
||||
}
|
||||
|
||||
void CWallet::ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey)
|
||||
|
|
|
@ -508,8 +508,8 @@ public:
|
|||
int i;
|
||||
int nDepth;
|
||||
|
||||
/** Pre-computed estimated size of this output as a fully-signed input in a transaction. Can be -1 if it could not be calculated */
|
||||
int nInputBytes;
|
||||
/** estimated size of this output as a fully-signed input in a transaction. Can be -1 */
|
||||
mutable int nInputBytes;
|
||||
|
||||
/** Whether we have the private keys to spend this output */
|
||||
bool fSpendable;
|
||||
|
@ -527,20 +527,22 @@ public:
|
|||
*/
|
||||
bool fSafe;
|
||||
|
||||
COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn, bool fSolvableIn, bool fSafeIn, bool use_max_sig_in = false)
|
||||
COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn,
|
||||
bool fSolvableIn, bool fSafeIn, bool use_max_sig_in = false)
|
||||
: tx(txIn), i(iIn), nDepth(nDepthIn), fSpendable(fSpendableIn), fSolvable(fSolvableIn),
|
||||
fSafe(fSafeIn), nInputBytes(-1), use_max_sig(use_max_sig_in)
|
||||
{
|
||||
tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; fSolvable = fSolvableIn; fSafe = fSafeIn; nInputBytes = -1; use_max_sig = use_max_sig_in;
|
||||
// If known and signable by the given wallet, compute nInputBytes
|
||||
// Failure will keep this value -1
|
||||
if (fSpendable && tx) {
|
||||
nInputBytes = tx->GetSpendSize(i, use_max_sig);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
inline CInputCoin GetInputCoin() const
|
||||
{
|
||||
// If known and signable by the given wallet, compute nInputBytes
|
||||
// Failure will keep this value -1
|
||||
if (nInputBytes < 0 && fSpendable && tx) {
|
||||
nInputBytes = tx->GetSpendSize(i, use_max_sig);
|
||||
}
|
||||
return CInputCoin(tx->tx, i, nInputBytes);
|
||||
}
|
||||
};
|
||||
|
@ -850,7 +852,7 @@ public:
|
|||
/**
|
||||
* populate vCoins with vector of available COutputs.
|
||||
*/
|
||||
void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlySafe=true, const CCoinControl *coinControl = nullptr, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t nMaximumCount = 0, const int nMinDepth = 0, const int nMaxDepth = 9999999) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlySafe=true, const CCoinControl *coinControl = nullptr, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t nMaximumCount = 0, const int nMinDepth = 0, const int nMaxDepth = 9999999, bool computeSolvable=false) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
/**
|
||||
* Return list of available coins and locked coins grouped by non-change output address.
|
||||
|
|
Loading…
Reference in a new issue