mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
Merge #6447: [v22.0.x] backport: v22.0.0 rc.3
c7b0d80939
Merge #6441: fix: hold wallet shared pointer in CJ Manager/Sessions to prevent concurrent unload (pasta)c074e0965b
Merge #6444: fix: add platform transfer to "most common" filter (pasta)cb04114143
Merge #6442: fix: coin selection with `include_unsafe` option should respect `nCoinType` (pasta)db5b53a9a7
Merge #6434: fix: early EHF and buried EHF are indistinguish (pasta) Pull request description: ## Issue being fixed or feature implemented See commits; backports for rc.3 ## What was done? ## How Has This Been Tested? built locally ## Breaking Changes ## Checklist: _Go over all the following points, and put an `x` in all the boxes that apply._ - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: kwvg: ACKc7b0d80939
UdjinM6: utACKc7b0d80939
Tree-SHA512: a64d6503a845ea86df8660d34cdf819c6fefcae5e82035bd8de40152f4f7d894cd1870315b791cca81e6d4db08d9929e4d1de3338a0338478072c9e6bb66952a
This commit is contained in:
commit
e0151e3dfe
@ -160,7 +160,7 @@ void CCoinJoinClientManager::ProcessMessage(CNode& peer, CChainState& active_cha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CCoinJoinClientSession::CCoinJoinClientSession(CWallet& wallet, CoinJoinWalletManager& walletman,
|
CCoinJoinClientSession::CCoinJoinClientSession(const std::shared_ptr<CWallet>& wallet, CoinJoinWalletManager& walletman,
|
||||||
CCoinJoinClientManager& clientman, CDeterministicMNManager& dmnman,
|
CCoinJoinClientManager& clientman, CDeterministicMNManager& dmnman,
|
||||||
CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync,
|
CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync,
|
||||||
const std::unique_ptr<CCoinJoinClientQueueManager>& queueman,
|
const std::unique_ptr<CCoinJoinClientQueueManager>& queueman,
|
||||||
@ -258,7 +258,7 @@ void CCoinJoinClientSession::ResetPool()
|
|||||||
{
|
{
|
||||||
txMyCollateral = CMutableTransaction();
|
txMyCollateral = CMutableTransaction();
|
||||||
UnlockCoins();
|
UnlockCoins();
|
||||||
WITH_LOCK(m_wallet.cs_wallet, keyHolderStorage.ReturnAll());
|
WITH_LOCK(m_wallet->cs_wallet, keyHolderStorage.ReturnAll());
|
||||||
WITH_LOCK(cs_coinjoin, SetNull());
|
WITH_LOCK(cs_coinjoin, SetNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,13 +292,13 @@ void CCoinJoinClientSession::UnlockCoins()
|
|||||||
if (!CCoinJoinClientOptions::IsEnabled()) return;
|
if (!CCoinJoinClientOptions::IsEnabled()) return;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
TRY_LOCK(m_wallet.cs_wallet, lockWallet);
|
TRY_LOCK(m_wallet->cs_wallet, lockWallet);
|
||||||
if (!lockWallet) {
|
if (!lockWallet) {
|
||||||
UninterruptibleSleep(std::chrono::milliseconds{50});
|
UninterruptibleSleep(std::chrono::milliseconds{50});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (const auto& outpoint : vecOutPointLocked)
|
for (const auto& outpoint : vecOutPointLocked)
|
||||||
m_wallet.UnlockCoin(outpoint);
|
m_wallet->UnlockCoin(outpoint);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,7 +419,7 @@ bool CCoinJoinClientSession::CheckTimeout()
|
|||||||
|
|
||||||
SetState(POOL_STATE_ERROR);
|
SetState(POOL_STATE_ERROR);
|
||||||
UnlockCoins();
|
UnlockCoins();
|
||||||
WITH_LOCK(m_wallet.cs_wallet, keyHolderStorage.ReturnAll());
|
WITH_LOCK(m_wallet->cs_wallet, keyHolderStorage.ReturnAll());
|
||||||
nTimeLastSuccessfulStep = GetTime();
|
nTimeLastSuccessfulStep = GetTime();
|
||||||
strLastMessage = CoinJoin::GetMessageByID(ERR_SESSION);
|
strLastMessage = CoinJoin::GetMessageByID(ERR_SESSION);
|
||||||
|
|
||||||
@ -530,7 +530,7 @@ void CCoinJoinClientSession::ProcessPoolStateUpdate(CCoinJoinStatusUpdate psssup
|
|||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- rejected by Masternode: %s\n", __func__, strMessageTmp.translated);
|
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- rejected by Masternode: %s\n", __func__, strMessageTmp.translated);
|
||||||
SetState(POOL_STATE_ERROR);
|
SetState(POOL_STATE_ERROR);
|
||||||
UnlockCoins();
|
UnlockCoins();
|
||||||
WITH_LOCK(m_wallet.cs_wallet, keyHolderStorage.ReturnAll());
|
WITH_LOCK(m_wallet->cs_wallet, keyHolderStorage.ReturnAll());
|
||||||
nTimeLastSuccessfulStep = GetTime();
|
nTimeLastSuccessfulStep = GetTime();
|
||||||
strLastMessage = strMessageTmp;
|
strLastMessage = strMessageTmp;
|
||||||
break;
|
break;
|
||||||
@ -564,7 +564,7 @@ bool CCoinJoinClientSession::SignFinalTransaction(CNode& peer, CChainState& acti
|
|||||||
if (m_is_masternode) return false;
|
if (m_is_masternode) return false;
|
||||||
if (!mixingMasternode) return false;
|
if (!mixingMasternode) return false;
|
||||||
|
|
||||||
LOCK(m_wallet.cs_wallet);
|
LOCK(m_wallet->cs_wallet);
|
||||||
LOCK(cs_coinjoin);
|
LOCK(cs_coinjoin);
|
||||||
|
|
||||||
finalMutableTransaction = CMutableTransaction{finalTransactionNew};
|
finalMutableTransaction = CMutableTransaction{finalTransactionNew};
|
||||||
@ -646,9 +646,9 @@ bool CCoinJoinClientSession::SignFinalTransaction(CNode& peer, CChainState& acti
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fill values for found outpoints
|
// fill values for found outpoints
|
||||||
m_wallet.chain().findCoins(coins);
|
m_wallet->chain().findCoins(coins);
|
||||||
std::map<int, bilingual_str> signing_errors;
|
std::map<int, bilingual_str> signing_errors;
|
||||||
m_wallet.SignTransaction(finalMutableTransaction, coins, SIGHASH_ALL | SIGHASH_ANYONECANPAY, signing_errors);
|
m_wallet->SignTransaction(finalMutableTransaction, coins, SIGHASH_ALL | SIGHASH_ANYONECANPAY, signing_errors);
|
||||||
|
|
||||||
for (const auto& [input_index, error_string] : signing_errors) {
|
for (const auto& [input_index, error_string] : signing_errors) {
|
||||||
// NOTE: this is a partial signing so it's expected for SignTransaction to return
|
// NOTE: this is a partial signing so it's expected for SignTransaction to return
|
||||||
@ -697,7 +697,7 @@ void CCoinJoinClientSession::CompletedTransaction(PoolMessage nMessageID)
|
|||||||
keyHolderStorage.KeepAll();
|
keyHolderStorage.KeepAll();
|
||||||
WalletCJLogPrint(m_wallet, "CompletedTransaction -- success\n");
|
WalletCJLogPrint(m_wallet, "CompletedTransaction -- success\n");
|
||||||
} else {
|
} else {
|
||||||
WITH_LOCK(m_wallet.cs_wallet, keyHolderStorage.ReturnAll());
|
WITH_LOCK(m_wallet->cs_wallet, keyHolderStorage.ReturnAll());
|
||||||
WalletCJLogPrint(m_wallet, "CompletedTransaction -- error\n");
|
WalletCJLogPrint(m_wallet, "CompletedTransaction -- error\n");
|
||||||
}
|
}
|
||||||
UnlockCoins();
|
UnlockCoins();
|
||||||
@ -725,14 +725,14 @@ bool CCoinJoinClientManager::CheckAutomaticBackup()
|
|||||||
if (!CCoinJoinClientOptions::IsEnabled() || !IsMixing()) return false;
|
if (!CCoinJoinClientOptions::IsEnabled() || !IsMixing()) return false;
|
||||||
|
|
||||||
// We don't need auto-backups for descriptor wallets
|
// We don't need auto-backups for descriptor wallets
|
||||||
if (!m_wallet.IsLegacy()) return true;
|
if (!m_wallet->IsLegacy()) return true;
|
||||||
|
|
||||||
switch (nWalletBackups) {
|
switch (nWalletBackups) {
|
||||||
case 0:
|
case 0:
|
||||||
strAutoDenomResult = _("Automatic backups disabled") + Untranslated(", ") + _("no mixing available.");
|
strAutoDenomResult = _("Automatic backups disabled") + Untranslated(", ") + _("no mixing available.");
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientManager::CheckAutomaticBackup -- %s\n", strAutoDenomResult.original);
|
WalletCJLogPrint(m_wallet, "CCoinJoinClientManager::CheckAutomaticBackup -- %s\n", strAutoDenomResult.original);
|
||||||
StopMixing();
|
StopMixing();
|
||||||
m_wallet.nKeysLeftSinceAutoBackup = 0; // no backup, no "keys since last backup"
|
m_wallet->nKeysLeftSinceAutoBackup = 0; // no backup, no "keys since last backup"
|
||||||
return false;
|
return false;
|
||||||
case -1:
|
case -1:
|
||||||
// Automatic backup failed, nothing else we can do until user fixes the issue manually.
|
// Automatic backup failed, nothing else we can do until user fixes the issue manually.
|
||||||
@ -750,16 +750,18 @@ bool CCoinJoinClientManager::CheckAutomaticBackup()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_wallet.nKeysLeftSinceAutoBackup < COINJOIN_KEYS_THRESHOLD_STOP) {
|
if (m_wallet->nKeysLeftSinceAutoBackup < COINJOIN_KEYS_THRESHOLD_STOP) {
|
||||||
// We should never get here via mixing itself but probably something else is still actively using keypool
|
// We should never get here via mixing itself but probably something else is still actively using keypool
|
||||||
strAutoDenomResult = strprintf(_("Very low number of keys left: %d") + Untranslated(", ") + _("no mixing available."), m_wallet.nKeysLeftSinceAutoBackup);
|
strAutoDenomResult = strprintf(_("Very low number of keys left: %d") + Untranslated(", ") +
|
||||||
|
_("no mixing available."),
|
||||||
|
m_wallet->nKeysLeftSinceAutoBackup);
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientManager::CheckAutomaticBackup -- %s\n", strAutoDenomResult.original);
|
WalletCJLogPrint(m_wallet, "CCoinJoinClientManager::CheckAutomaticBackup -- %s\n", strAutoDenomResult.original);
|
||||||
// It's getting really dangerous, stop mixing
|
// It's getting really dangerous, stop mixing
|
||||||
StopMixing();
|
StopMixing();
|
||||||
return false;
|
return false;
|
||||||
} else if (m_wallet.nKeysLeftSinceAutoBackup < COINJOIN_KEYS_THRESHOLD_WARNING) {
|
} else if (m_wallet->nKeysLeftSinceAutoBackup < COINJOIN_KEYS_THRESHOLD_WARNING) {
|
||||||
// Low number of keys left, but it's still more or less safe to continue
|
// Low number of keys left, but it's still more or less safe to continue
|
||||||
strAutoDenomResult = strprintf(_("Very low number of keys left: %d"), m_wallet.nKeysLeftSinceAutoBackup);
|
strAutoDenomResult = strprintf(_("Very low number of keys left: %d"), m_wallet->nKeysLeftSinceAutoBackup);
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientManager::CheckAutomaticBackup -- %s\n", strAutoDenomResult.original);
|
WalletCJLogPrint(m_wallet, "CCoinJoinClientManager::CheckAutomaticBackup -- %s\n", strAutoDenomResult.original);
|
||||||
|
|
||||||
if (fCreateAutoBackups) {
|
if (fCreateAutoBackups) {
|
||||||
@ -767,7 +769,7 @@ bool CCoinJoinClientManager::CheckAutomaticBackup()
|
|||||||
bilingual_str errorString;
|
bilingual_str errorString;
|
||||||
std::vector<bilingual_str> warnings;
|
std::vector<bilingual_str> warnings;
|
||||||
|
|
||||||
if (!m_wallet.AutoBackupWallet("", errorString, warnings)) {
|
if (!m_wallet->AutoBackupWallet("", errorString, warnings)) {
|
||||||
if (!warnings.empty()) {
|
if (!warnings.empty()) {
|
||||||
// There were some issues saving backup but yet more or less safe to continue
|
// There were some issues saving backup but yet more or less safe to continue
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientManager::CheckAutomaticBackup -- WARNING! Something went wrong on automatic backup: %s\n", Join(warnings, Untranslated("\n")).translated);
|
WalletCJLogPrint(m_wallet, "CCoinJoinClientManager::CheckAutomaticBackup -- WARNING! Something went wrong on automatic backup: %s\n", Join(warnings, Untranslated("\n")).translated);
|
||||||
@ -785,7 +787,8 @@ bool CCoinJoinClientManager::CheckAutomaticBackup()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientManager::CheckAutomaticBackup -- Keys left since latest backup: %d\n", m_wallet.nKeysLeftSinceAutoBackup);
|
WalletCJLogPrint(m_wallet, "CCoinJoinClientManager::CheckAutomaticBackup -- Keys left since latest backup: %d\n",
|
||||||
|
m_wallet->nKeysLeftSinceAutoBackup);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -809,9 +812,9 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(ChainstateManager& chainman
|
|||||||
CAmount nBalanceNeedsAnonymized;
|
CAmount nBalanceNeedsAnonymized;
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK(m_wallet.cs_wallet);
|
LOCK(m_wallet->cs_wallet);
|
||||||
|
|
||||||
if (!fDryRun && m_wallet.IsLocked(true)) {
|
if (!fDryRun && m_wallet->IsLocked(true)) {
|
||||||
strAutoDenomResult = _("Wallet is locked.");
|
strAutoDenomResult = _("Wallet is locked.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -834,7 +837,7 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(ChainstateManager& chainman
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto bal = m_wallet.GetBalance();
|
const auto bal = m_wallet->GetBalance();
|
||||||
|
|
||||||
// check if there is anything left to do
|
// check if there is anything left to do
|
||||||
CAmount nBalanceAnonymized = bal.m_anonymized;
|
CAmount nBalanceAnonymized = bal.m_anonymized;
|
||||||
@ -849,13 +852,13 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(ChainstateManager& chainman
|
|||||||
CAmount nValueMin = CoinJoin::GetSmallestDenomination();
|
CAmount nValueMin = CoinJoin::GetSmallestDenomination();
|
||||||
|
|
||||||
// if there are no confirmed DS collateral inputs yet
|
// if there are no confirmed DS collateral inputs yet
|
||||||
if (!m_wallet.HasCollateralInputs()) {
|
if (!m_wallet->HasCollateralInputs()) {
|
||||||
// should have some additional amount for them
|
// should have some additional amount for them
|
||||||
nValueMin += CoinJoin::GetMaxCollateralAmount();
|
nValueMin += CoinJoin::GetMaxCollateralAmount();
|
||||||
}
|
}
|
||||||
|
|
||||||
// including denoms but applying some restrictions
|
// including denoms but applying some restrictions
|
||||||
CAmount nBalanceAnonymizable = m_wallet.GetAnonymizableBalance();
|
CAmount nBalanceAnonymizable = m_wallet->GetAnonymizableBalance();
|
||||||
|
|
||||||
// mixable balance is way too small
|
// mixable balance is way too small
|
||||||
if (nBalanceAnonymizable < nValueMin) {
|
if (nBalanceAnonymizable < nValueMin) {
|
||||||
@ -865,7 +868,7 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(ChainstateManager& chainman
|
|||||||
}
|
}
|
||||||
|
|
||||||
// excluding denoms
|
// excluding denoms
|
||||||
CAmount nBalanceAnonimizableNonDenom = m_wallet.GetAnonymizableBalance(true);
|
CAmount nBalanceAnonimizableNonDenom = m_wallet->GetAnonymizableBalance(true);
|
||||||
// denoms
|
// denoms
|
||||||
CAmount nBalanceDenominatedConf = bal.m_denominated_trusted;
|
CAmount nBalanceDenominatedConf = bal.m_denominated_trusted;
|
||||||
CAmount nBalanceDenominatedUnconf = bal.m_denominated_untrusted_pending;
|
CAmount nBalanceDenominatedUnconf = bal.m_denominated_untrusted_pending;
|
||||||
@ -917,8 +920,8 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(ChainstateManager& chainman
|
|||||||
}
|
}
|
||||||
|
|
||||||
//check if we have the collateral sized inputs
|
//check if we have the collateral sized inputs
|
||||||
if (!m_wallet.HasCollateralInputs()) {
|
if (!m_wallet->HasCollateralInputs()) {
|
||||||
return !m_wallet.HasCollateralInputs(false) && MakeCollateralAmounts();
|
return !m_wallet->HasCollateralInputs(false) && MakeCollateralAmounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nSessionID) {
|
if (nSessionID) {
|
||||||
@ -957,10 +960,10 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(ChainstateManager& chainman
|
|||||||
}
|
}
|
||||||
// lock the funds we're going to use for our collateral
|
// lock the funds we're going to use for our collateral
|
||||||
for (const auto& txin : txMyCollateral.vin) {
|
for (const auto& txin : txMyCollateral.vin) {
|
||||||
m_wallet.LockCoin(txin.prevout);
|
m_wallet->LockCoin(txin.prevout);
|
||||||
vecOutPointLocked.push_back(txin.prevout);
|
vecOutPointLocked.push_back(txin.prevout);
|
||||||
}
|
}
|
||||||
} // LOCK(m_wallet.cs_wallet);
|
} // LOCK(m_wallet->cs_wallet);
|
||||||
|
|
||||||
// Always attempt to join an existing queue
|
// Always attempt to join an existing queue
|
||||||
if (JoinExistingQueue(nBalanceNeedsAnonymized, connman)) {
|
if (JoinExistingQueue(nBalanceNeedsAnonymized, connman)) {
|
||||||
@ -985,7 +988,7 @@ bool CCoinJoinClientManager::DoAutomaticDenominating(ChainstateManager& chainman
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fDryRun && m_wallet.IsLocked(true)) {
|
if (!fDryRun && m_wallet->IsLocked(true)) {
|
||||||
strAutoDenomResult = _("Wallet is locked.");
|
strAutoDenomResult = _("Wallet is locked.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1107,7 +1110,7 @@ bool CCoinJoinClientSession::JoinExistingQueue(CAmount nBalanceNeedsAnonymized,
|
|||||||
std::vector<CTxDSIn> vecTxDSInTmp;
|
std::vector<CTxDSIn> vecTxDSInTmp;
|
||||||
|
|
||||||
// Try to match their denominations if possible, select exact number of denominations
|
// Try to match their denominations if possible, select exact number of denominations
|
||||||
if (!m_wallet.SelectTxDSInsByDenomination(dsq.nDenom, nBalanceNeedsAnonymized, vecTxDSInTmp)) {
|
if (!m_wallet->SelectTxDSInsByDenomination(dsq.nDenom, nBalanceNeedsAnonymized, vecTxDSInTmp)) {
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::JoinExistingQueue -- Couldn't match denomination %d (%s)\n", dsq.nDenom, CoinJoin::DenominationToString(dsq.nDenom));
|
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::JoinExistingQueue -- Couldn't match denomination %d (%s)\n", dsq.nDenom, CoinJoin::DenominationToString(dsq.nDenom));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1153,7 +1156,7 @@ bool CCoinJoinClientSession::StartNewQueue(CAmount nBalanceNeedsAnonymized, CCon
|
|||||||
|
|
||||||
// find available denominated amounts
|
// find available denominated amounts
|
||||||
std::set<CAmount> setAmounts;
|
std::set<CAmount> setAmounts;
|
||||||
if (!m_wallet.SelectDenominatedAmounts(nBalanceNeedsAnonymized, setAmounts)) {
|
if (!m_wallet->SelectDenominatedAmounts(nBalanceNeedsAnonymized, setAmounts)) {
|
||||||
// this should never happen
|
// this should never happen
|
||||||
strAutoDenomResult = _("Can't mix: no compatible inputs found!");
|
strAutoDenomResult = _("Can't mix: no compatible inputs found!");
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::StartNewQueue -- %s\n", strAutoDenomResult.original);
|
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::StartNewQueue -- %s\n", strAutoDenomResult.original);
|
||||||
@ -1288,7 +1291,7 @@ bool CCoinJoinClientManager::MarkAlreadyJoinedQueueAsTried(CCoinJoinQueue& dsq)
|
|||||||
|
|
||||||
bool CCoinJoinClientSession::SubmitDenominate(CConnman& connman)
|
bool CCoinJoinClientSession::SubmitDenominate(CConnman& connman)
|
||||||
{
|
{
|
||||||
LOCK(m_wallet.cs_wallet);
|
LOCK(m_wallet->cs_wallet);
|
||||||
|
|
||||||
std::string strError;
|
std::string strError;
|
||||||
std::vector<CTxDSIn> vecTxDSIn;
|
std::vector<CTxDSIn> vecTxDSIn;
|
||||||
@ -1342,7 +1345,7 @@ bool CCoinJoinClientSession::SelectDenominate(std::string& strErrorRet, std::vec
|
|||||||
{
|
{
|
||||||
if (!CCoinJoinClientOptions::IsEnabled()) return false;
|
if (!CCoinJoinClientOptions::IsEnabled()) return false;
|
||||||
|
|
||||||
if (m_wallet.IsLocked(true)) {
|
if (m_wallet->IsLocked(true)) {
|
||||||
strErrorRet = "Wallet locked, unable to create transaction!";
|
strErrorRet = "Wallet locked, unable to create transaction!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1354,7 +1357,7 @@ bool CCoinJoinClientSession::SelectDenominate(std::string& strErrorRet, std::vec
|
|||||||
|
|
||||||
vecTxDSInRet.clear();
|
vecTxDSInRet.clear();
|
||||||
|
|
||||||
bool fSelected = m_wallet.SelectTxDSInsByDenomination(nSessionDenom, CoinJoin::GetMaxPoolAmount(), vecTxDSInRet);
|
bool fSelected = m_wallet->SelectTxDSInsByDenomination(nSessionDenom, CoinJoin::GetMaxPoolAmount(), vecTxDSInRet);
|
||||||
if (!fSelected) {
|
if (!fSelected) {
|
||||||
strErrorRet = "Can't select current denominated inputs";
|
strErrorRet = "Can't select current denominated inputs";
|
||||||
return false;
|
return false;
|
||||||
@ -1365,7 +1368,7 @@ bool CCoinJoinClientSession::SelectDenominate(std::string& strErrorRet, std::vec
|
|||||||
|
|
||||||
bool CCoinJoinClientSession::PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, const std::vector<CTxDSIn>& vecTxDSIn, std::vector<std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsRet, bool fDryRun)
|
bool CCoinJoinClientSession::PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, const std::vector<CTxDSIn>& vecTxDSIn, std::vector<std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsRet, bool fDryRun)
|
||||||
{
|
{
|
||||||
AssertLockHeld(m_wallet.cs_wallet);
|
AssertLockHeld(m_wallet->cs_wallet);
|
||||||
|
|
||||||
if (!CoinJoin::IsValidDenomination(nSessionDenom)) {
|
if (!CoinJoin::IsValidDenomination(nSessionDenom)) {
|
||||||
strErrorRet = "Incorrect session denom";
|
strErrorRet = "Incorrect session denom";
|
||||||
@ -1395,12 +1398,7 @@ bool CCoinJoinClientSession::PrepareDenominate(int nMinRounds, int nMaxRounds, s
|
|||||||
++nSteps;
|
++nSteps;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto pwallet = GetWallet(m_wallet.GetName());
|
scriptDenom = keyHolderStorage.AddKey(m_wallet.get());
|
||||||
if (!pwallet) {
|
|
||||||
strErrorRet ="Couldn't get wallet pointer";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
scriptDenom = keyHolderStorage.AddKey(pwallet.get());
|
|
||||||
}
|
}
|
||||||
vecPSInOutPairsRet.emplace_back(entry, CTxOut(nDenomAmount, scriptDenom));
|
vecPSInOutPairsRet.emplace_back(entry, CTxOut(nDenomAmount, scriptDenom));
|
||||||
// step is complete
|
// step is complete
|
||||||
@ -1418,7 +1416,7 @@ bool CCoinJoinClientSession::PrepareDenominate(int nMinRounds, int nMaxRounds, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& [txDsIn, txDsOut] : vecPSInOutPairsRet) {
|
for (const auto& [txDsIn, txDsOut] : vecPSInOutPairsRet) {
|
||||||
m_wallet.LockCoin(txDsIn.prevout);
|
m_wallet->LockCoin(txDsIn.prevout);
|
||||||
vecOutPointLocked.push_back(txDsIn.prevout);
|
vecOutPointLocked.push_back(txDsIn.prevout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1430,13 +1428,13 @@ bool CCoinJoinClientSession::MakeCollateralAmounts()
|
|||||||
{
|
{
|
||||||
if (!CCoinJoinClientOptions::IsEnabled()) return false;
|
if (!CCoinJoinClientOptions::IsEnabled()) return false;
|
||||||
|
|
||||||
LOCK(m_wallet.cs_wallet);
|
LOCK(m_wallet->cs_wallet);
|
||||||
|
|
||||||
// NOTE: We do not allow txes larger than 100 kB, so we have to limit number of inputs here.
|
// NOTE: We do not allow txes larger than 100 kB, so we have to limit number of inputs here.
|
||||||
// We still want to consume a lot of inputs to avoid creating only smaller denoms though.
|
// We still want to consume a lot of inputs to avoid creating only smaller denoms though.
|
||||||
// Knowing that each CTxIn is at least 148 B big, 400 inputs should take 400 x ~148 B = ~60 kB.
|
// Knowing that each CTxIn is at least 148 B big, 400 inputs should take 400 x ~148 B = ~60 kB.
|
||||||
// This still leaves more than enough room for another data of typical MakeCollateralAmounts tx.
|
// This still leaves more than enough room for another data of typical MakeCollateralAmounts tx.
|
||||||
std::vector<CompactTallyItem> vecTally = m_wallet.SelectCoinsGroupedByAddresses(false, false, true, 400);
|
std::vector<CompactTallyItem> vecTally = m_wallet->SelectCoinsGroupedByAddresses(false, false, true, 400);
|
||||||
if (vecTally.empty()) {
|
if (vecTally.empty()) {
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::MakeCollateralAmounts -- SelectCoinsGroupedByAddresses can't find any inputs!\n");
|
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::MakeCollateralAmounts -- SelectCoinsGroupedByAddresses can't find any inputs!\n");
|
||||||
return false;
|
return false;
|
||||||
@ -1448,14 +1446,14 @@ bool CCoinJoinClientSession::MakeCollateralAmounts()
|
|||||||
});
|
});
|
||||||
|
|
||||||
// First try to use only non-denominated funds
|
// First try to use only non-denominated funds
|
||||||
if (ranges::any_of(vecTally, [&](const auto& item) EXCLUSIVE_LOCKS_REQUIRED(m_wallet.cs_wallet) {
|
if (ranges::any_of(vecTally, [&](const auto& item) EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet) {
|
||||||
return MakeCollateralAmounts(item, false);
|
return MakeCollateralAmounts(item, false);
|
||||||
})) {
|
})) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There should be at least some denominated funds we should be able to break in pieces to continue mixing
|
// There should be at least some denominated funds we should be able to break in pieces to continue mixing
|
||||||
if (ranges::any_of(vecTally, [&](const auto& item) EXCLUSIVE_LOCKS_REQUIRED(m_wallet.cs_wallet) {
|
if (ranges::any_of(vecTally, [&](const auto& item) EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet) {
|
||||||
return MakeCollateralAmounts(item, true);
|
return MakeCollateralAmounts(item, true);
|
||||||
})) {
|
})) {
|
||||||
return true;
|
return true;
|
||||||
@ -1470,7 +1468,7 @@ bool CCoinJoinClientSession::MakeCollateralAmounts()
|
|||||||
bool CCoinJoinClientSession::MakeCollateralAmounts(const CompactTallyItem& tallyItem, bool fTryDenominated)
|
bool CCoinJoinClientSession::MakeCollateralAmounts(const CompactTallyItem& tallyItem, bool fTryDenominated)
|
||||||
{
|
{
|
||||||
// TODO: consider refactoring to remove duplicated code with CCoinJoinClientSession::CreateDenominated
|
// TODO: consider refactoring to remove duplicated code with CCoinJoinClientSession::CreateDenominated
|
||||||
AssertLockHeld(m_wallet.cs_wallet);
|
AssertLockHeld(m_wallet->cs_wallet);
|
||||||
|
|
||||||
if (!CCoinJoinClientOptions::IsEnabled()) return false;
|
if (!CCoinJoinClientOptions::IsEnabled()) return false;
|
||||||
|
|
||||||
@ -1484,14 +1482,7 @@ bool CCoinJoinClientSession::MakeCollateralAmounts(const CompactTallyItem& tally
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto pwallet = GetWallet(m_wallet.GetName());
|
CTransactionBuilder txBuilder(m_wallet, tallyItem);
|
||||||
|
|
||||||
if (!pwallet) {
|
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- Couldn't get wallet pointer\n", __func__);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CTransactionBuilder txBuilder(pwallet, tallyItem);
|
|
||||||
|
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- Start %s\n", __func__, txBuilder.ToString());
|
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- Start %s\n", __func__, txBuilder.ToString());
|
||||||
|
|
||||||
@ -1562,13 +1553,13 @@ bool CCoinJoinClientSession::MakeCollateralAmounts(const CompactTallyItem& tally
|
|||||||
|
|
||||||
bool CCoinJoinClientSession::CreateCollateralTransaction(CMutableTransaction& txCollateral, std::string& strReason)
|
bool CCoinJoinClientSession::CreateCollateralTransaction(CMutableTransaction& txCollateral, std::string& strReason)
|
||||||
{
|
{
|
||||||
AssertLockHeld(m_wallet.cs_wallet);
|
AssertLockHeld(m_wallet->cs_wallet);
|
||||||
|
|
||||||
std::vector<COutput> vCoins;
|
std::vector<COutput> vCoins;
|
||||||
CCoinControl coin_control;
|
CCoinControl coin_control;
|
||||||
coin_control.nCoinType = CoinType::ONLY_COINJOIN_COLLATERAL;
|
coin_control.nCoinType = CoinType::ONLY_COINJOIN_COLLATERAL;
|
||||||
|
|
||||||
m_wallet.AvailableCoins(vCoins, &coin_control);
|
m_wallet->AvailableCoins(vCoins, &coin_control);
|
||||||
|
|
||||||
if (vCoins.empty()) {
|
if (vCoins.empty()) {
|
||||||
strReason = strprintf("%s requires a collateral transaction and could not locate an acceptable input!", gCoinJoinName);
|
strReason = strprintf("%s requires a collateral transaction and could not locate an acceptable input!", gCoinJoinName);
|
||||||
@ -1589,7 +1580,7 @@ bool CCoinJoinClientSession::CreateCollateralTransaction(CMutableTransaction& tx
|
|||||||
// make our change address
|
// make our change address
|
||||||
CScript scriptChange;
|
CScript scriptChange;
|
||||||
CTxDestination dest;
|
CTxDestination dest;
|
||||||
ReserveDestination reserveDest(&m_wallet);
|
ReserveDestination reserveDest(m_wallet.get());
|
||||||
bool success = reserveDest.GetReservedDestination(dest, true);
|
bool success = reserveDest.GetReservedDestination(dest, true);
|
||||||
assert(success); // should never fail, as we just unlocked
|
assert(success); // should never fail, as we just unlocked
|
||||||
scriptChange = GetScriptForDestination(dest);
|
scriptChange = GetScriptForDestination(dest);
|
||||||
@ -1601,7 +1592,7 @@ bool CCoinJoinClientSession::CreateCollateralTransaction(CMutableTransaction& tx
|
|||||||
txCollateral.vout.emplace_back(0, CScript() << OP_RETURN);
|
txCollateral.vout.emplace_back(0, CScript() << OP_RETURN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_wallet.SignTransaction(txCollateral)) {
|
if (!m_wallet->SignTransaction(txCollateral)) {
|
||||||
strReason = "Unable to sign collateral transaction!";
|
strReason = "Unable to sign collateral transaction!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1614,13 +1605,13 @@ bool CCoinJoinClientSession::CreateDenominated(CAmount nBalanceToDenominate)
|
|||||||
{
|
{
|
||||||
if (!CCoinJoinClientOptions::IsEnabled()) return false;
|
if (!CCoinJoinClientOptions::IsEnabled()) return false;
|
||||||
|
|
||||||
LOCK(m_wallet.cs_wallet);
|
LOCK(m_wallet->cs_wallet);
|
||||||
|
|
||||||
// NOTE: We do not allow txes larger than 100 kB, so we have to limit number of inputs here.
|
// NOTE: We do not allow txes larger than 100 kB, so we have to limit number of inputs here.
|
||||||
// We still want to consume a lot of inputs to avoid creating only smaller denoms though.
|
// We still want to consume a lot of inputs to avoid creating only smaller denoms though.
|
||||||
// Knowing that each CTxIn is at least 148 B big, 400 inputs should take 400 x ~148 B = ~60 kB.
|
// Knowing that each CTxIn is at least 148 B big, 400 inputs should take 400 x ~148 B = ~60 kB.
|
||||||
// This still leaves more than enough room for another data of typical CreateDenominated tx.
|
// This still leaves more than enough room for another data of typical CreateDenominated tx.
|
||||||
std::vector<CompactTallyItem> vecTally = m_wallet.SelectCoinsGroupedByAddresses(true, true, true, 400);
|
std::vector<CompactTallyItem> vecTally = m_wallet->SelectCoinsGroupedByAddresses(true, true, true, 400);
|
||||||
if (vecTally.empty()) {
|
if (vecTally.empty()) {
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::CreateDenominated -- SelectCoinsGroupedByAddresses can't find any inputs!\n");
|
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::CreateDenominated -- SelectCoinsGroupedByAddresses can't find any inputs!\n");
|
||||||
return false;
|
return false;
|
||||||
@ -1631,7 +1622,7 @@ bool CCoinJoinClientSession::CreateDenominated(CAmount nBalanceToDenominate)
|
|||||||
return a.nAmount > b.nAmount;
|
return a.nAmount > b.nAmount;
|
||||||
});
|
});
|
||||||
|
|
||||||
bool fCreateMixingCollaterals = !m_wallet.HasCollateralInputs();
|
bool fCreateMixingCollaterals = !m_wallet->HasCollateralInputs();
|
||||||
|
|
||||||
for (const auto& item : vecTally) {
|
for (const auto& item : vecTally) {
|
||||||
if (!CreateDenominated(nBalanceToDenominate, item, fCreateMixingCollaterals)) continue;
|
if (!CreateDenominated(nBalanceToDenominate, item, fCreateMixingCollaterals)) continue;
|
||||||
@ -1645,7 +1636,7 @@ bool CCoinJoinClientSession::CreateDenominated(CAmount nBalanceToDenominate)
|
|||||||
// Create denominations
|
// Create denominations
|
||||||
bool CCoinJoinClientSession::CreateDenominated(CAmount nBalanceToDenominate, const CompactTallyItem& tallyItem, bool fCreateMixingCollaterals)
|
bool CCoinJoinClientSession::CreateDenominated(CAmount nBalanceToDenominate, const CompactTallyItem& tallyItem, bool fCreateMixingCollaterals)
|
||||||
{
|
{
|
||||||
AssertLockHeld(m_wallet.cs_wallet);
|
AssertLockHeld(m_wallet->cs_wallet);
|
||||||
|
|
||||||
if (!CCoinJoinClientOptions::IsEnabled()) return false;
|
if (!CCoinJoinClientOptions::IsEnabled()) return false;
|
||||||
|
|
||||||
@ -1654,14 +1645,7 @@ bool CCoinJoinClientSession::CreateDenominated(CAmount nBalanceToDenominate, con
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto pwallet = GetWallet(m_wallet.GetName());
|
CTransactionBuilder txBuilder(m_wallet, tallyItem);
|
||||||
|
|
||||||
if (!pwallet) {
|
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- Couldn't get wallet pointer\n", __func__);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CTransactionBuilder txBuilder(pwallet, tallyItem);
|
|
||||||
|
|
||||||
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- Start %s\n", __func__, txBuilder.ToString());
|
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- Start %s\n", __func__, txBuilder.ToString());
|
||||||
|
|
||||||
@ -1679,7 +1663,7 @@ bool CCoinJoinClientSession::CreateDenominated(CAmount nBalanceToDenominate, con
|
|||||||
|
|
||||||
std::map<CAmount, int> mapDenomCount;
|
std::map<CAmount, int> mapDenomCount;
|
||||||
for (auto nDenomValue : denoms) {
|
for (auto nDenomValue : denoms) {
|
||||||
mapDenomCount.insert(std::pair<CAmount, int>(nDenomValue, m_wallet.CountInputsWithAmount(nDenomValue)));
|
mapDenomCount.insert(std::pair<CAmount, int>(nDenomValue, m_wallet->CountInputsWithAmount(nDenomValue)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will generate outputs for the createdenoms up to coinjoinmaxdenoms per denom
|
// Will generate outputs for the createdenoms up to coinjoinmaxdenoms per denom
|
||||||
@ -1922,11 +1906,11 @@ void CCoinJoinClientManager::GetJsonInfo(UniValue& obj) const
|
|||||||
obj.pushKV("sessions", arrSessions);
|
obj.pushKV("sessions", arrSessions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoinJoinWalletManager::Add(CWallet& wallet)
|
void CoinJoinWalletManager::Add(const std::shared_ptr<CWallet>& wallet)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet_manager_map);
|
LOCK(cs_wallet_manager_map);
|
||||||
m_wallet_manager_map.try_emplace(wallet.GetName(),
|
m_wallet_manager_map.try_emplace(wallet->GetName(),
|
||||||
std::make_unique<CCoinJoinClientManager>(wallet, *this, m_dmnman, m_mn_metaman,
|
std::make_unique<CCoinJoinClientManager>(wallet, *this, m_dmnman, m_mn_metaman,
|
||||||
m_mn_sync, m_queueman, m_is_masternode));
|
m_mn_sync, m_queueman, m_is_masternode));
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Add(CWallet& wallet);
|
void Add(const std::shared_ptr<CWallet>& wallet);
|
||||||
void DoMaintenance();
|
void DoMaintenance();
|
||||||
|
|
||||||
void Remove(const std::string& name);
|
void Remove(const std::string& name);
|
||||||
@ -138,7 +138,7 @@ private:
|
|||||||
class CCoinJoinClientSession : public CCoinJoinBaseSession
|
class CCoinJoinClientSession : public CCoinJoinBaseSession
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
CWallet& m_wallet;
|
const std::shared_ptr<CWallet> m_wallet;
|
||||||
CoinJoinWalletManager& m_walletman;
|
CoinJoinWalletManager& m_walletman;
|
||||||
CCoinJoinClientManager& m_clientman;
|
CCoinJoinClientManager& m_clientman;
|
||||||
CDeterministicMNManager& m_dmnman;
|
CDeterministicMNManager& m_dmnman;
|
||||||
@ -163,15 +163,15 @@ private:
|
|||||||
/// Create denominations
|
/// Create denominations
|
||||||
bool CreateDenominated(CAmount nBalanceToDenominate);
|
bool CreateDenominated(CAmount nBalanceToDenominate);
|
||||||
bool CreateDenominated(CAmount nBalanceToDenominate, const CompactTallyItem& tallyItem, bool fCreateMixingCollaterals)
|
bool CreateDenominated(CAmount nBalanceToDenominate, const CompactTallyItem& tallyItem, bool fCreateMixingCollaterals)
|
||||||
EXCLUSIVE_LOCKS_REQUIRED(m_wallet.cs_wallet);
|
EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet);
|
||||||
|
|
||||||
/// Split up large inputs or make fee sized inputs
|
/// Split up large inputs or make fee sized inputs
|
||||||
bool MakeCollateralAmounts();
|
bool MakeCollateralAmounts();
|
||||||
bool MakeCollateralAmounts(const CompactTallyItem& tallyItem, bool fTryDenominated)
|
bool MakeCollateralAmounts(const CompactTallyItem& tallyItem, bool fTryDenominated)
|
||||||
EXCLUSIVE_LOCKS_REQUIRED(m_wallet.cs_wallet);
|
EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet);
|
||||||
|
|
||||||
bool CreateCollateralTransaction(CMutableTransaction& txCollateral, std::string& strReason)
|
bool CreateCollateralTransaction(CMutableTransaction& txCollateral, std::string& strReason)
|
||||||
EXCLUSIVE_LOCKS_REQUIRED(m_wallet.cs_wallet);
|
EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet);
|
||||||
|
|
||||||
bool JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CConnman& connman);
|
bool JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CConnman& connman);
|
||||||
bool StartNewQueue(CAmount nBalanceNeedsAnonymized, CConnman& connman);
|
bool StartNewQueue(CAmount nBalanceNeedsAnonymized, CConnman& connman);
|
||||||
@ -181,7 +181,7 @@ private:
|
|||||||
/// step 1: prepare denominated inputs and outputs
|
/// step 1: prepare denominated inputs and outputs
|
||||||
bool PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, const std::vector<CTxDSIn>& vecTxDSIn,
|
bool PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, const std::vector<CTxDSIn>& vecTxDSIn,
|
||||||
std::vector<std::pair<CTxDSIn, CTxOut>>& vecPSInOutPairsRet, bool fDryRun = false)
|
std::vector<std::pair<CTxDSIn, CTxOut>>& vecPSInOutPairsRet, bool fDryRun = false)
|
||||||
EXCLUSIVE_LOCKS_REQUIRED(m_wallet.cs_wallet);
|
EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet);
|
||||||
/// step 2: send denominated inputs and outputs prepared in step 1
|
/// step 2: send denominated inputs and outputs prepared in step 1
|
||||||
bool SendDenominate(const std::vector<std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsIn, CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);
|
bool SendDenominate(const std::vector<std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsIn, CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ private:
|
|||||||
void SetNull() override EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin);
|
void SetNull() override EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CCoinJoinClientSession(CWallet& wallet, CoinJoinWalletManager& walletman,
|
explicit CCoinJoinClientSession(const std::shared_ptr<CWallet>& wallet, CoinJoinWalletManager& walletman,
|
||||||
CCoinJoinClientManager& clientman, CDeterministicMNManager& dmnman,
|
CCoinJoinClientManager& clientman, CDeterministicMNManager& dmnman,
|
||||||
CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync,
|
CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync,
|
||||||
const std::unique_ptr<CCoinJoinClientQueueManager>& queueman, bool is_masternode);
|
const std::unique_ptr<CCoinJoinClientQueueManager>& queueman, bool is_masternode);
|
||||||
@ -267,7 +267,7 @@ public:
|
|||||||
class CCoinJoinClientManager
|
class CCoinJoinClientManager
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
CWallet& m_wallet;
|
const std::shared_ptr<CWallet> m_wallet;
|
||||||
CoinJoinWalletManager& m_walletman;
|
CoinJoinWalletManager& m_walletman;
|
||||||
CDeterministicMNManager& m_dmnman;
|
CDeterministicMNManager& m_dmnman;
|
||||||
CMasternodeMetaMan& m_mn_metaman;
|
CMasternodeMetaMan& m_mn_metaman;
|
||||||
@ -306,11 +306,19 @@ public:
|
|||||||
CCoinJoinClientManager(CCoinJoinClientManager const&) = delete;
|
CCoinJoinClientManager(CCoinJoinClientManager const&) = delete;
|
||||||
CCoinJoinClientManager& operator=(CCoinJoinClientManager const&) = delete;
|
CCoinJoinClientManager& operator=(CCoinJoinClientManager const&) = delete;
|
||||||
|
|
||||||
explicit CCoinJoinClientManager(CWallet& wallet, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman,
|
explicit CCoinJoinClientManager(const std::shared_ptr<CWallet>& wallet, CoinJoinWalletManager& walletman,
|
||||||
CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync,
|
CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman,
|
||||||
|
const CMasternodeSync& mn_sync,
|
||||||
const std::unique_ptr<CCoinJoinClientQueueManager>& queueman, bool is_masternode) :
|
const std::unique_ptr<CCoinJoinClientQueueManager>& queueman, bool is_masternode) :
|
||||||
m_wallet(wallet), m_walletman(walletman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), m_queueman(queueman),
|
m_wallet(wallet),
|
||||||
m_is_masternode{is_masternode} {}
|
m_walletman(walletman),
|
||||||
|
m_dmnman(dmnman),
|
||||||
|
m_mn_metaman(mn_metaman),
|
||||||
|
m_mn_sync(mn_sync),
|
||||||
|
m_queueman(queueman),
|
||||||
|
m_is_masternode{is_masternode}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void ProcessMessage(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
|
void ProcessMessage(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
|
||||||
|
|
||||||
|
@ -67,10 +67,7 @@ public:
|
|||||||
explicit CoinJoinLoaderImpl(CoinJoinWalletManager& walletman)
|
explicit CoinJoinLoaderImpl(CoinJoinWalletManager& walletman)
|
||||||
: m_walletman(walletman) {}
|
: m_walletman(walletman) {}
|
||||||
|
|
||||||
void AddWallet(CWallet& wallet) override
|
void AddWallet(const std::shared_ptr<CWallet>& wallet) override { m_walletman.Add(wallet); }
|
||||||
{
|
|
||||||
m_walletman.Add(wallet);
|
|
||||||
}
|
|
||||||
void RemoveWallet(const std::string& name) override
|
void RemoveWallet(const std::string& name) override
|
||||||
{
|
{
|
||||||
m_walletman.Remove(name);
|
m_walletman.Remove(name);
|
||||||
|
@ -87,14 +87,15 @@ void CKeyHolderStorage::ReturnAll()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CTransactionBuilderOutput::CTransactionBuilderOutput(CTransactionBuilder* pTxBuilderIn, std::shared_ptr<CWallet> pwalletIn, CAmount nAmountIn) :
|
CTransactionBuilderOutput::CTransactionBuilderOutput(CTransactionBuilder* pTxBuilderIn,
|
||||||
|
const std::shared_ptr<CWallet>& wallet, CAmount nAmountIn) :
|
||||||
pTxBuilder(pTxBuilderIn),
|
pTxBuilder(pTxBuilderIn),
|
||||||
dest(pwalletIn.get()),
|
dest(wallet.get()),
|
||||||
nAmount(nAmountIn)
|
nAmount(nAmountIn)
|
||||||
{
|
{
|
||||||
assert(pTxBuilder);
|
assert(pTxBuilder);
|
||||||
CTxDestination txdest;
|
CTxDestination txdest;
|
||||||
LOCK(pwalletIn->cs_wallet);
|
LOCK(wallet->cs_wallet);
|
||||||
dest.GetReservedDestination(txdest, false);
|
dest.GetReservedDestination(txdest, false);
|
||||||
script = ::GetScriptForDestination(txdest);
|
script = ::GetScriptForDestination(txdest);
|
||||||
}
|
}
|
||||||
@ -108,15 +109,15 @@ bool CTransactionBuilderOutput::UpdateAmount(const CAmount nNewAmount)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CTransactionBuilder::CTransactionBuilder(std::shared_ptr<CWallet> pwalletIn, const CompactTallyItem& tallyItemIn) :
|
CTransactionBuilder::CTransactionBuilder(const std::shared_ptr<CWallet>& wallet, const CompactTallyItem& tallyItemIn) :
|
||||||
pwallet(pwalletIn),
|
m_wallet(wallet),
|
||||||
dummyReserveDestination(pwalletIn.get()),
|
dummyReserveDestination(wallet.get()),
|
||||||
tallyItem(tallyItemIn)
|
tallyItem(tallyItemIn)
|
||||||
{
|
{
|
||||||
// Generate a feerate which will be used to consider if the remainder is dust and will go into fees or not
|
// Generate a feerate which will be used to consider if the remainder is dust and will go into fees or not
|
||||||
coinControl.m_discard_feerate = ::GetDiscardRate(*pwallet);
|
coinControl.m_discard_feerate = ::GetDiscardRate(*m_wallet);
|
||||||
// Generate a feerate which will be used by calculations of this class and also by CWallet::CreateTransaction
|
// Generate a feerate which will be used by calculations of this class and also by CWallet::CreateTransaction
|
||||||
coinControl.m_feerate = std::max(GetRequiredFeeRate(*pwallet), pwallet->m_pay_tx_fee);
|
coinControl.m_feerate = std::max(GetRequiredFeeRate(*m_wallet), m_wallet->m_pay_tx_fee);
|
||||||
// Change always goes back to origin
|
// Change always goes back to origin
|
||||||
coinControl.destChange = tallyItemIn.txdest;
|
coinControl.destChange = tallyItemIn.txdest;
|
||||||
// Only allow tallyItems inputs for tx creation
|
// Only allow tallyItems inputs for tx creation
|
||||||
@ -131,16 +132,16 @@ CTransactionBuilder::CTransactionBuilder(std::shared_ptr<CWallet> pwalletIn, con
|
|||||||
// Get a comparable dummy scriptPubKey, avoid writing/flushing to the actual wallet db
|
// Get a comparable dummy scriptPubKey, avoid writing/flushing to the actual wallet db
|
||||||
CScript dummyScript;
|
CScript dummyScript;
|
||||||
{
|
{
|
||||||
LOCK(pwallet->cs_wallet);
|
LOCK(m_wallet->cs_wallet);
|
||||||
WalletBatch dummyBatch(pwallet->GetDatabase(), false);
|
WalletBatch dummyBatch(m_wallet->GetDatabase(), false);
|
||||||
dummyBatch.TxnBegin();
|
dummyBatch.TxnBegin();
|
||||||
CKey secret;
|
CKey secret;
|
||||||
secret.MakeNewKey(pwallet->CanSupportFeature(FEATURE_COMPRPUBKEY));
|
secret.MakeNewKey(m_wallet->CanSupportFeature(FEATURE_COMPRPUBKEY));
|
||||||
CPubKey dummyPubkey = secret.GetPubKey();
|
CPubKey dummyPubkey = secret.GetPubKey();
|
||||||
dummyBatch.TxnAbort();
|
dummyBatch.TxnAbort();
|
||||||
dummyScript = ::GetScriptForDestination(PKHash(dummyPubkey));
|
dummyScript = ::GetScriptForDestination(PKHash(dummyPubkey));
|
||||||
// Calculate required bytes for the dummy signed tx with tallyItem's inputs only
|
// Calculate required bytes for the dummy signed tx with tallyItem's inputs only
|
||||||
nBytesBase = CalculateMaximumSignedTxSize(CTransaction(dummyTx), pwallet.get(), false);
|
nBytesBase = CalculateMaximumSignedTxSize(CTransaction(dummyTx), m_wallet.get(), false);
|
||||||
}
|
}
|
||||||
// Calculate the output size
|
// Calculate the output size
|
||||||
nBytesOutput = ::GetSerializeSize(CTxOut(0, dummyScript), PROTOCOL_VERSION);
|
nBytesOutput = ::GetSerializeSize(CTxOut(0, dummyScript), PROTOCOL_VERSION);
|
||||||
@ -204,7 +205,7 @@ CTransactionBuilderOutput* CTransactionBuilder::AddOutput(CAmount nAmountOutput)
|
|||||||
{
|
{
|
||||||
if (CouldAddOutput(nAmountOutput)) {
|
if (CouldAddOutput(nAmountOutput)) {
|
||||||
LOCK(cs_outputs);
|
LOCK(cs_outputs);
|
||||||
vecOutputs.push_back(std::make_unique<CTransactionBuilderOutput>(this, pwallet, nAmountOutput));
|
vecOutputs.push_back(std::make_unique<CTransactionBuilderOutput>(this, m_wallet, nAmountOutput));
|
||||||
return vecOutputs.back().get();
|
return vecOutputs.back().get();
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -233,12 +234,12 @@ CAmount CTransactionBuilder::GetAmountUsed() const
|
|||||||
CAmount CTransactionBuilder::GetFee(unsigned int nBytes) const
|
CAmount CTransactionBuilder::GetFee(unsigned int nBytes) const
|
||||||
{
|
{
|
||||||
CAmount nFeeCalc = coinControl.m_feerate->GetFee(nBytes);
|
CAmount nFeeCalc = coinControl.m_feerate->GetFee(nBytes);
|
||||||
CAmount nRequiredFee = GetRequiredFee(*pwallet, nBytes);
|
CAmount nRequiredFee = GetRequiredFee(*m_wallet, nBytes);
|
||||||
if (nRequiredFee > nFeeCalc) {
|
if (nRequiredFee > nFeeCalc) {
|
||||||
nFeeCalc = nRequiredFee;
|
nFeeCalc = nRequiredFee;
|
||||||
}
|
}
|
||||||
if (nFeeCalc > pwallet->m_default_max_tx_fee) {
|
if (nFeeCalc > m_wallet->m_default_max_tx_fee) {
|
||||||
nFeeCalc = pwallet->m_default_max_tx_fee;
|
nFeeCalc = m_wallet->m_default_max_tx_fee;
|
||||||
}
|
}
|
||||||
return nFeeCalc;
|
return nFeeCalc;
|
||||||
}
|
}
|
||||||
@ -273,9 +274,9 @@ bool CTransactionBuilder::Commit(bilingual_str& strResult)
|
|||||||
|
|
||||||
CTransactionRef tx;
|
CTransactionRef tx;
|
||||||
{
|
{
|
||||||
LOCK2(pwallet->cs_wallet, cs_main);
|
LOCK2(m_wallet->cs_wallet, cs_main);
|
||||||
FeeCalculation fee_calc_out;
|
FeeCalculation fee_calc_out;
|
||||||
if (!pwallet->CreateTransaction(vecSend, tx, nFeeRet, nChangePosRet, strResult, coinControl, fee_calc_out)) {
|
if (!m_wallet->CreateTransaction(vecSend, tx, nFeeRet, nChangePosRet, strResult, coinControl, fee_calc_out)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,8 +313,8 @@ bool CTransactionBuilder::Commit(bilingual_str& strResult)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK2(pwallet->cs_wallet, cs_main);
|
LOCK2(m_wallet->cs_wallet, cs_main);
|
||||||
pwallet->CommitTransaction(tx, {}, {});
|
m_wallet->CommitTransaction(tx, {}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
fKeepKeys = true;
|
fKeepKeys = true;
|
||||||
|
@ -54,7 +54,7 @@ class CTransactionBuilderOutput
|
|||||||
CScript script;
|
CScript script;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CTransactionBuilderOutput(CTransactionBuilder* pTxBuilderIn, std::shared_ptr<CWallet> pwalletIn, CAmount nAmountIn);
|
CTransactionBuilderOutput(CTransactionBuilder* pTxBuilderIn, const std::shared_ptr<CWallet>& wallet, CAmount nAmountIn);
|
||||||
CTransactionBuilderOutput(CTransactionBuilderOutput&&) = delete;
|
CTransactionBuilderOutput(CTransactionBuilderOutput&&) = delete;
|
||||||
CTransactionBuilderOutput& operator=(CTransactionBuilderOutput&&) = delete;
|
CTransactionBuilderOutput& operator=(CTransactionBuilderOutput&&) = delete;
|
||||||
/// Get the scriptPubKey of this output
|
/// Get the scriptPubKey of this output
|
||||||
@ -77,7 +77,7 @@ public:
|
|||||||
class CTransactionBuilder
|
class CTransactionBuilder
|
||||||
{
|
{
|
||||||
/// Wallet the transaction will be build for
|
/// Wallet the transaction will be build for
|
||||||
std::shared_ptr<CWallet> pwallet;
|
const std::shared_ptr<CWallet>& m_wallet;
|
||||||
/// See CTransactionBuilder() for initialization
|
/// See CTransactionBuilder() for initialization
|
||||||
CCoinControl coinControl;
|
CCoinControl coinControl;
|
||||||
/// Dummy since we anyway use tallyItem's destination as change destination in coincontrol.
|
/// Dummy since we anyway use tallyItem's destination as change destination in coincontrol.
|
||||||
@ -100,7 +100,7 @@ class CTransactionBuilder
|
|||||||
friend class CTransactionBuilderOutput;
|
friend class CTransactionBuilderOutput;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CTransactionBuilder(std::shared_ptr<CWallet> pwalletIn, const CompactTallyItem& tallyItemIn);
|
CTransactionBuilder(const std::shared_ptr<CWallet>& wallet, const CompactTallyItem& tallyItemIn);
|
||||||
~CTransactionBuilder();
|
~CTransactionBuilder();
|
||||||
/// Check it would be possible to add a single output with the amount nAmount. Returns true if its possible and false if not.
|
/// Check it would be possible to add a single output with the amount nAmount. Returns true if its possible and false if not.
|
||||||
bool CouldAddOutput(CAmount nAmountOutput) const EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs);
|
bool CouldAddOutput(CAmount nAmountOutput) const EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
static const std::string MNEHF_REQUESTID_PREFIX = "mnhf";
|
static const std::string MNEHF_REQUESTID_PREFIX = "mnhf";
|
||||||
static const std::string DB_SIGNALS = "mnhf_s";
|
static const std::string DB_SIGNALS = "mnhf_s";
|
||||||
|
static const std::string DB_SIGNALS_v2 = "mnhf_s2";
|
||||||
|
|
||||||
uint256 MNHFTxPayload::GetRequestId() const
|
uint256 MNHFTxPayload::GetRequestId() const
|
||||||
{
|
{
|
||||||
@ -57,34 +58,33 @@ CMNHFManager::Signals CMNHFManager::GetSignalsStage(const CBlockIndex* const pin
|
|||||||
{
|
{
|
||||||
if (!DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return {};
|
if (!DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return {};
|
||||||
|
|
||||||
Signals signals = GetForBlock(pindexPrev);
|
Signals signals_tmp = GetForBlock(pindexPrev);
|
||||||
|
|
||||||
if (pindexPrev == nullptr) return {};
|
if (pindexPrev == nullptr) return {};
|
||||||
const int height = pindexPrev->nHeight + 1;
|
const int height = pindexPrev->nHeight + 1;
|
||||||
for (auto it = signals.begin(); it != signals.end(); ) {
|
|
||||||
bool found{false};
|
Signals signals_ret;
|
||||||
const auto signal_pindex = pindexPrev->GetAncestor(it->second);
|
|
||||||
|
for (auto signal : signals_tmp) {
|
||||||
|
bool expired{false};
|
||||||
|
const auto signal_pindex = pindexPrev->GetAncestor(signal.second);
|
||||||
assert(signal_pindex != nullptr);
|
assert(signal_pindex != nullptr);
|
||||||
const int64_t signal_time = signal_pindex->GetMedianTimePast();
|
const int64_t signal_time = signal_pindex->GetMedianTimePast();
|
||||||
for (int index = 0; index < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++index) {
|
for (int index = 0; index < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++index) {
|
||||||
const auto& deployment = Params().GetConsensus().vDeployments[index];
|
const auto& deployment = Params().GetConsensus().vDeployments[index];
|
||||||
if (deployment.bit != it->first) continue;
|
if (deployment.bit != signal.first) continue;
|
||||||
if (signal_time < deployment.nStartTime) {
|
if (signal_time < deployment.nStartTime) {
|
||||||
// new deployment is using the same bit as the old one
|
// new deployment is using the same bit as the old one
|
||||||
LogPrintf("CMNHFManager::GetSignalsStage: mnhf signal bit=%d height:%d is expired at height=%d\n", it->first, it->second, height);
|
LogPrintf("CMNHFManager::GetSignalsStage: mnhf signal bit=%d height:%d is expired at height=%d\n",
|
||||||
it = signals.erase(it);
|
signal.first, signal.second, height);
|
||||||
} else {
|
expired = true;
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!expired) {
|
||||||
// no deployment means we buried it and aren't using the same bit (yet)
|
signals_ret.insert(signal);
|
||||||
LogPrintf("CMNHFManager::GetSignalsStage: mnhf signal bit=%d height:%d is not known at height=%d\n", it->first, it->second, height);
|
|
||||||
it = signals.erase(it);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return signals;
|
return signals_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MNHFTx::Verify(const llmq::CQuorumManager& qman, const uint256& quorumHash, const uint256& requestId, const uint256& msgHash, TxValidationState& state) const
|
bool MNHFTx::Verify(const llmq::CQuorumManager& qman, const uint256& quorumHash, const uint256& requestId, const uint256& msgHash, TxValidationState& state) const
|
||||||
@ -287,6 +287,9 @@ CMNHFManager::Signals CMNHFManager::GetForBlock(const CBlockIndex* pindex)
|
|||||||
const Consensus::Params& consensusParams{Params().GetConsensus()};
|
const Consensus::Params& consensusParams{Params().GetConsensus()};
|
||||||
while (!to_calculate.empty()) {
|
while (!to_calculate.empty()) {
|
||||||
const CBlockIndex* pindex_top{to_calculate.top()};
|
const CBlockIndex* pindex_top{to_calculate.top()};
|
||||||
|
if (pindex_top->nHeight % 1000 == 0) {
|
||||||
|
LogPrintf("re-index EHF signals at block %d\n", pindex_top->nHeight);
|
||||||
|
}
|
||||||
CBlock block;
|
CBlock block;
|
||||||
if (!ReadBlockFromDisk(block, pindex_top, consensusParams)) {
|
if (!ReadBlockFromDisk(block, pindex_top, consensusParams)) {
|
||||||
throw std::runtime_error("failed-getehfforblock-read");
|
throw std::runtime_error("failed-getehfforblock-read");
|
||||||
@ -328,11 +331,19 @@ std::optional<CMNHFManager::Signals> CMNHFManager::GetFromCache(const CBlockInde
|
|||||||
return signals;
|
return signals;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_evoDb.Read(std::make_pair(DB_SIGNALS, blockHash), signals)) {
|
if (m_evoDb.Read(std::make_pair(DB_SIGNALS_v2, blockHash), signals)) {
|
||||||
LOCK(cs_cache);
|
LOCK(cs_cache);
|
||||||
mnhfCache.insert(blockHash, signals);
|
mnhfCache.insert(blockHash, signals);
|
||||||
return signals;
|
return signals;
|
||||||
}
|
}
|
||||||
|
if (!DeploymentActiveAt(*pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR)) {
|
||||||
|
// before mn_rr activation we are safe
|
||||||
|
if (m_evoDb.Read(std::make_pair(DB_SIGNALS, blockHash), signals)) {
|
||||||
|
LOCK(cs_cache);
|
||||||
|
mnhfCache.insert(blockHash, signals);
|
||||||
|
return signals;
|
||||||
|
}
|
||||||
|
}
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,7 +357,7 @@ void CMNHFManager::AddToCache(const Signals& signals, const CBlockIndex* const p
|
|||||||
}
|
}
|
||||||
if (!DeploymentActiveAt(*pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return;
|
if (!DeploymentActiveAt(*pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return;
|
||||||
|
|
||||||
m_evoDb.Write(std::make_pair(DB_SIGNALS, blockHash), signals);
|
m_evoDb.Write(std::make_pair(DB_SIGNALS_v2, blockHash), signals);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMNHFManager::AddSignal(const CBlockIndex* const pindex, int bit)
|
void CMNHFManager::AddSignal(const CBlockIndex* const pindex, int bit)
|
||||||
@ -364,6 +375,25 @@ void CMNHFManager::ConnectManagers(gsl::not_null<ChainstateManager*> chainman, g
|
|||||||
m_qman = qman;
|
m_qman = qman;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CMNHFManager::ForceSignalDBUpdate()
|
||||||
|
{
|
||||||
|
// force ehf signals db update
|
||||||
|
auto dbTx = m_evoDb.BeginTransaction();
|
||||||
|
|
||||||
|
const bool last_legacy = bls::bls_legacy_scheme.load();
|
||||||
|
bls::bls_legacy_scheme.store(false);
|
||||||
|
GetSignalsStage(m_chainman->ActiveChainstate().m_chain.Tip());
|
||||||
|
bls::bls_legacy_scheme.store(last_legacy);
|
||||||
|
|
||||||
|
dbTx->Commit();
|
||||||
|
// flush it to disk
|
||||||
|
if (!m_evoDb.CommitRootTransaction()) {
|
||||||
|
LogPrintf("CMNHFManager::%s -- failed to commit to evoDB\n", __func__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::string MNHFTx::ToString() const
|
std::string MNHFTx::ToString() const
|
||||||
{
|
{
|
||||||
return strprintf("MNHFTx(versionBit=%d, quorumHash=%s, sig=%s)",
|
return strprintf("MNHFTx(versionBit=%d, quorumHash=%s, sig=%s)",
|
||||||
|
@ -155,6 +155,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
void DisconnectManagers() { m_chainman = nullptr; m_qman = nullptr; };
|
void DisconnectManagers() { m_chainman = nullptr; m_qman = nullptr; };
|
||||||
|
|
||||||
|
bool ForceSignalDBUpdate() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AddToCache(const Signals& signals, const CBlockIndex* const pindex);
|
void AddToCache(const Signals& signals, const CBlockIndex* const pindex);
|
||||||
|
|
||||||
|
@ -2064,6 +2064,10 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||||||
strLoadError = _("Error upgrading evo database");
|
strLoadError = _("Error upgrading evo database");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!node.mnhf_manager->ForceSignalDBUpdate()) {
|
||||||
|
strLoadError = _("Error upgrading evo database for EHF");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for (CChainState* chainstate : chainman.GetAll()) {
|
for (CChainState* chainstate : chainman.GetAll()) {
|
||||||
if (!is_coinsview_empty(chainstate)) {
|
if (!is_coinsview_empty(chainstate)) {
|
||||||
|
@ -33,7 +33,7 @@ class Loader
|
|||||||
public:
|
public:
|
||||||
virtual ~Loader() {}
|
virtual ~Loader() {}
|
||||||
//! Add new wallet to CoinJoin client manager
|
//! Add new wallet to CoinJoin client manager
|
||||||
virtual void AddWallet(CWallet&) = 0;
|
virtual void AddWallet(const std::shared_ptr<CWallet>&) = 0;
|
||||||
//! Remove wallet from CoinJoin client manager
|
//! Remove wallet from CoinJoin client manager
|
||||||
virtual void RemoveWallet(const std::string&) = 0;
|
virtual void RemoveWallet(const std::string&) = 0;
|
||||||
virtual void FlushWallet(const std::string&) = 0;
|
virtual void FlushWallet(const std::string&) = 0;
|
||||||
|
@ -23,7 +23,7 @@ public:
|
|||||||
/** Type filter bit field (all types) */
|
/** Type filter bit field (all types) */
|
||||||
static const quint32 ALL_TYPES = 0xFFFFFFFF;
|
static const quint32 ALL_TYPES = 0xFFFFFFFF;
|
||||||
/** Type filter bit field (all types but Darksend-SPAM) */
|
/** Type filter bit field (all types but Darksend-SPAM) */
|
||||||
static const quint32 COMMON_TYPES = 4223;
|
static const quint32 COMMON_TYPES = 0x307f;
|
||||||
|
|
||||||
static quint32 TYPE(int type) { return 1<<type; }
|
static quint32 TYPE(int type) { return 1<<type; }
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ public:
|
|||||||
class TransactionRecord
|
class TransactionRecord
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// Update COMMON_TYPES in TransactionFilterProxyWhen when adding a new type
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
Other,
|
Other,
|
||||||
|
@ -59,6 +59,10 @@ static std::shared_ptr<CWallet> TestLoadWallet(interfaces::Chain* chain, interfa
|
|||||||
std::vector<bilingual_str> warnings;
|
std::vector<bilingual_str> warnings;
|
||||||
auto database = MakeWalletDatabase("", options, status, error);
|
auto database = MakeWalletDatabase("", options, status, error);
|
||||||
auto wallet = CWallet::Create(chain, coinjoin_loader, "", std::move(database), options.create_flags, error, warnings);
|
auto wallet = CWallet::Create(chain, coinjoin_loader, "", std::move(database), options.create_flags, error, warnings);
|
||||||
|
if (coinjoin_loader) {
|
||||||
|
// TODO: see CreateWalletWithoutChain
|
||||||
|
AddWallet(wallet);
|
||||||
|
}
|
||||||
if (chain) {
|
if (chain) {
|
||||||
wallet->postInitProcess();
|
wallet->postInitProcess();
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ bool AddWallet(const std::shared_ptr<CWallet>& wallet)
|
|||||||
}
|
}
|
||||||
wallet->ConnectScriptPubKeyManNotifiers();
|
wallet->ConnectScriptPubKeyManNotifiers();
|
||||||
wallet->AutoLockMasternodeCollaterals();
|
wallet->AutoLockMasternodeCollaterals();
|
||||||
wallet->coinjoin_loader().AddWallet(*wallet);
|
wallet->coinjoin_loader().AddWallet(wallet);
|
||||||
wallet->NotifyCanGetAddressesChanged();
|
wallet->NotifyCanGetAddressesChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1432,7 +1432,7 @@ int CWallet::GetRealOutpointCoinJoinRounds(const COutPoint& outpoint, int nRound
|
|||||||
if (wtx == nullptr || wtx->tx == nullptr) {
|
if (wtx == nullptr || wtx->tx == nullptr) {
|
||||||
// no such tx in this wallet
|
// no such tx in this wallet
|
||||||
*nRoundsRef = -1;
|
*nRoundsRef = -1;
|
||||||
WalletCJLogPrint((*this), "%s FAILED %-70s %3d\n", __func__, outpoint.ToStringShort(), -1);
|
WalletCJLogPrint(this, "%s FAILED %-70s %3d\n", __func__, outpoint.ToStringShort(), -1);
|
||||||
return *nRoundsRef;
|
return *nRoundsRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1440,7 +1440,7 @@ int CWallet::GetRealOutpointCoinJoinRounds(const COutPoint& outpoint, int nRound
|
|||||||
if (outpoint.n >= wtx->tx->vout.size()) {
|
if (outpoint.n >= wtx->tx->vout.size()) {
|
||||||
// should never actually hit this
|
// should never actually hit this
|
||||||
*nRoundsRef = -4;
|
*nRoundsRef = -4;
|
||||||
WalletCJLogPrint((*this), "%s FAILED %-70s %3d\n", __func__, outpoint.ToStringShort(), -4);
|
WalletCJLogPrint(this, "%s FAILED %-70s %3d\n", __func__, outpoint.ToStringShort(), -4);
|
||||||
return *nRoundsRef;
|
return *nRoundsRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1448,14 +1448,14 @@ int CWallet::GetRealOutpointCoinJoinRounds(const COutPoint& outpoint, int nRound
|
|||||||
|
|
||||||
if (CoinJoin::IsCollateralAmount(txOutRef->nValue)) {
|
if (CoinJoin::IsCollateralAmount(txOutRef->nValue)) {
|
||||||
*nRoundsRef = -3;
|
*nRoundsRef = -3;
|
||||||
WalletCJLogPrint((*this), "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
WalletCJLogPrint(this, "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
||||||
return *nRoundsRef;
|
return *nRoundsRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the final output is non-denominate
|
// make sure the final output is non-denominate
|
||||||
if (!CoinJoin::IsDenominatedAmount(txOutRef->nValue)) { //NOT DENOM
|
if (!CoinJoin::IsDenominatedAmount(txOutRef->nValue)) { //NOT DENOM
|
||||||
*nRoundsRef = -2;
|
*nRoundsRef = -2;
|
||||||
WalletCJLogPrint((*this), "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
WalletCJLogPrint(this, "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
||||||
return *nRoundsRef;
|
return *nRoundsRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1463,7 +1463,7 @@ int CWallet::GetRealOutpointCoinJoinRounds(const COutPoint& outpoint, int nRound
|
|||||||
if (!CoinJoin::IsDenominatedAmount(out.nValue)) {
|
if (!CoinJoin::IsDenominatedAmount(out.nValue)) {
|
||||||
// this one is denominated but there is another non-denominated output found in the same tx
|
// this one is denominated but there is another non-denominated output found in the same tx
|
||||||
*nRoundsRef = 0;
|
*nRoundsRef = 0;
|
||||||
WalletCJLogPrint((*this), "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
WalletCJLogPrint(this, "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
||||||
return *nRoundsRef;
|
return *nRoundsRef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1471,7 +1471,7 @@ int CWallet::GetRealOutpointCoinJoinRounds(const COutPoint& outpoint, int nRound
|
|||||||
// make sure we spent all of it with 0 fee, reset to 0 rounds otherwise
|
// make sure we spent all of it with 0 fee, reset to 0 rounds otherwise
|
||||||
if (wtx->GetDebit(ISMINE_SPENDABLE) != wtx->GetCredit(ISMINE_SPENDABLE)) {
|
if (wtx->GetDebit(ISMINE_SPENDABLE) != wtx->GetCredit(ISMINE_SPENDABLE)) {
|
||||||
*nRoundsRef = 0;
|
*nRoundsRef = 0;
|
||||||
WalletCJLogPrint((*this), "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
WalletCJLogPrint(this, "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
||||||
return *nRoundsRef;
|
return *nRoundsRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1491,7 +1491,7 @@ int CWallet::GetRealOutpointCoinJoinRounds(const COutPoint& outpoint, int nRound
|
|||||||
*nRoundsRef = fDenomFound
|
*nRoundsRef = fDenomFound
|
||||||
? (nShortest >= nRoundsMax - 1 ? nRoundsMax : nShortest + 1) // good, we a +1 to the shortest one but only nRoundsMax rounds max allowed
|
? (nShortest >= nRoundsMax - 1 ? nRoundsMax : nShortest + 1) // good, we a +1 to the shortest one but only nRoundsMax rounds max allowed
|
||||||
: 0; // too bad, we are the fist one in that chain
|
: 0; // too bad, we are the fist one in that chain
|
||||||
WalletCJLogPrint((*this), "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
WalletCJLogPrint(this, "%s UPDATED %-70s %3d\n", __func__, outpoint.ToStringShort(), *nRoundsRef);
|
||||||
return *nRoundsRef;
|
return *nRoundsRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3041,7 +3041,7 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
|
|||||||
if (coin_control.m_include_unsafe_inputs
|
if (coin_control.m_include_unsafe_inputs
|
||||||
&& SelectCoinsMinConf(value_to_select,
|
&& SelectCoinsMinConf(value_to_select,
|
||||||
CoinEligibilityFilter(0 /* conf_mine */, 0 /* conf_theirs */, max_ancestors-1, max_descendants-1, true /* include_partial_groups */),
|
CoinEligibilityFilter(0 /* conf_mine */, 0 /* conf_theirs */, max_ancestors-1, max_descendants-1, true /* include_partial_groups */),
|
||||||
vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) {
|
vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used, nCoinType)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Try with unlimited ancestors/descendants. The transaction will still need to meet
|
// Try with unlimited ancestors/descendants. The transaction will still need to meet
|
||||||
@ -3253,7 +3253,7 @@ bool CWallet::SelectTxDSInsByDenomination(int nDenom, CAmount nValueMax, std::ve
|
|||||||
CCoinControl coin_control;
|
CCoinControl coin_control;
|
||||||
coin_control.nCoinType = CoinType::ONLY_READY_TO_MIX;
|
coin_control.nCoinType = CoinType::ONLY_READY_TO_MIX;
|
||||||
AvailableCoins(vCoins, &coin_control);
|
AvailableCoins(vCoins, &coin_control);
|
||||||
WalletCJLogPrint((*this), "CWallet::%s -- vCoins.size(): %d\n", __func__, vCoins.size());
|
WalletCJLogPrint(this, "CWallet::%s -- vCoins.size(): %d\n", __func__, vCoins.size());
|
||||||
|
|
||||||
Shuffle(vCoins.rbegin(), vCoins.rend(), FastRandomContext());
|
Shuffle(vCoins.rbegin(), vCoins.rend(), FastRandomContext());
|
||||||
|
|
||||||
@ -3271,11 +3271,11 @@ bool CWallet::SelectTxDSInsByDenomination(int nDenom, CAmount nValueMax, std::ve
|
|||||||
nValueTotal += nValue;
|
nValueTotal += nValue;
|
||||||
vecTxDSInRet.emplace_back(CTxDSIn(txin, scriptPubKey, nRounds));
|
vecTxDSInRet.emplace_back(CTxDSIn(txin, scriptPubKey, nRounds));
|
||||||
setRecentTxIds.emplace(txHash);
|
setRecentTxIds.emplace(txHash);
|
||||||
WalletCJLogPrint((*this), "CWallet::%s -- hash: %s, nValue: %d.%08d\n",
|
WalletCJLogPrint(this, "CWallet::%s -- hash: %s, nValue: %d.%08d\n",
|
||||||
__func__, txHash.ToString(), nValue / COIN, nValue % COIN);
|
__func__, txHash.ToString(), nValue / COIN, nValue % COIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletCJLogPrint((*this), "CWallet::%s -- setRecentTxIds.size(): %d\n", __func__, setRecentTxIds.size());
|
WalletCJLogPrint(this, "CWallet::%s -- setRecentTxIds.size(): %d\n", __func__, setRecentTxIds.size());
|
||||||
|
|
||||||
return nValueTotal > 0;
|
return nValueTotal > 0;
|
||||||
}
|
}
|
||||||
@ -4980,7 +4980,7 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain* chain, interfaces::C
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (coinjoin_loader) {
|
if (coinjoin_loader) {
|
||||||
coinjoin_loader->AddWallet(*walletInstance);
|
coinjoin_loader->AddWallet(walletInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -153,7 +153,7 @@ extern const std::map<uint64_t,std::string> WALLET_FLAG_CAVEATS;
|
|||||||
#define WalletCJLogPrint(wallet, ...) \
|
#define WalletCJLogPrint(wallet, ...) \
|
||||||
do { \
|
do { \
|
||||||
if (LogAcceptCategory(BCLog::COINJOIN)) { \
|
if (LogAcceptCategory(BCLog::COINJOIN)) { \
|
||||||
wallet.WalletLogPrintf(__VA_ARGS__); \
|
wallet->WalletLogPrintf(__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user