Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wallet: Remove calls to Chain::Lock methods #17954

Merged
merged 12 commits into from Apr 14, 2020
Merged

Conversation

ryanofsky
Copy link
Contributor

@ryanofsky ryanofsky commented Jan 17, 2020

This is a set of changes updating wallet code to make fewer calls to Chain::Lock methods, so the Chain::Lock class will be easier to remove in #16426 with fewer code changes and small changes to behavior.

@ryanofsky ryanofsky changed the title wallet: Remove calls to Chain::Lock methods in wallet wallet: Remove calls to Chain::Lock methods Jan 17, 2020
@jnewbery
Copy link
Contributor

Concept ACK

@DrahtBot
Copy link
Contributor

DrahtBot commented Jan 18, 2020

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

Copy link
Member

@ariard ariard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review ACK 1f4b604.

What do you think about caching also last block time at connection ? I think that would make some changes here better by avoiding to uselessly lock the node, even if it's through the interface.

uint256 GetLastBlockHash() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
{
AssertLockHeld(cs_wallet);
assert(m_last_block_processed_height >= 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cfc9373

It just occurs to me than this assert and the one in GetLastBlockHeight (than I introduced in 5aacc3e) are unsafe if we don't have a Chain interface from which to query block height at wallet creation (CreateWalletFromFile) but that's something to keep in mind if in the future you can run the wallet without a chain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cfc9373

It just occurs to me than this assert and the one in GetLastBlockHeight (than I introduced in 5aacc3e) are unsafe if we don't have a Chain interface from which to query block height at wallet creation (CreateWalletFromFile) but that's something to keep in mind if in the future you can run the wallet without a chain.

Yes, I think these cases would only be hit when running wallet code offline with the bitcoin-wallet tool or something similar. But if we add more offline features more code will have to change to be flexible about missing data

}
num_blocks = m_wallet->GetLastBlockHeight();
block_time = -1;
m_wallet->chain().findBlock(m_wallet->GetLastBlockHash(), nullptr, &block_time);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cfc9373

As noted in commit, we may have asynchronicity between node and wallet w.r.t block processing. So returned block time may not be the one of last block height. To avoid this we may cache block time to fetch it when needed with GetLastBlockTime. It would also remove some getBlockTime (but not all last time I looked on).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cfc9373

As noted in commit, we may have asynchronicity between node and wallet w.r.t block processing. So returned block time may not be the one of last block height. To avoid this we may cache block time to fetch it when needed with GetLastBlockTime. It would also remove some getBlockTime (but not all last time I looked on).

Just to be clear, height and time here should be in sync due to cs_wallet being held above. Could still cache the time though. Commit description is saying how the GUI display should be more up to date after this commit, because the transaction data and num blocks value will be in sync, instead of a higher num blocks being returned with older transaction data

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even further than cs_wallet, we are still holding cs_main there through the chain lock. When we're going to remove locked_chain we may have asynchronicity due to to height being based on BlockConnected locked by cs_wallet and findBlock locked by cs_main ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #17954 (comment)

(Relevant commit is cfc9373)

Even further than cs_wallet, we are still holding cs_main there through the chain lock. When we're going to remove locked_chain we may have asynchronicity due to to height being based on BlockConnected locked by cs_wallet and findBlock locked by cs_main ?

The GUI is asynchronous by design. It just needs to display internally consistent information within a transaction, and be able to determine if the information is fresh or out of date. The num_blocks height here returned to gui is used for that freshness check, so the new value set here should be better than the previous value for that. More ideally, though num_blocks will be replaced by a hash, which #17993 starts to do

src/wallet/rpcdump.cpp Outdated Show resolved Hide resolved
file << strprintf("# mined on %s\n", tip_height ? FormatISO8601DateTime(locked_chain->getBlockTime(*tip_height)) : "(missing block time)");
file << strprintf("# * Best block at time of backup was %i (%s),\n", pwallet->GetLastBlockHeight(), pwallet->GetLastBlockHash().ToString());
int64_t block_time = 0;
pwallet->chain().findBlock(pwallet->GetLastBlockHash(), nullptr, &block_time);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

673e0b6

Another candidate for GetLastBlockTime

@@ -564,8 +564,7 @@ UniValue importwallet(const JSONRPCRequest& request)
if (!file.is_open()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
}
Optional<int> tip_height = locked_chain->getHeight();
nTimeBegin = tip_height ? locked_chain->getBlockTime(*tip_height) : 0;
pwallet->chain().findBlock(pwallet->GetLastBlockHash(), nullptr, &nTimeBegin);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

673e0b6

I'm not sure about the commit message, IMO it's less accurate but on the whole make the rescan protection better by starting farther in the past. Anyway, being based on wallet tip or node tip should be safe given the range of TIMESTAMP_WINDOW

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

673e0b6

I'm not sure about the commit message, IMO it's less accurate but on the whole make the rescan protection better by starting farther in the past. Anyway, being based on wallet tip or node tip should be safe given the range of TIMESTAMP_WINDOW

Hmm, I'm not sure when it would be less accurate. Are you thinking of a case?

Copy link
Member

@ariard ariard Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #17954 (comment)

I think I meaned because we rely now on wallet last block hash instead of main tip and we may be late from one block, so in my opinion we are less accurate from one block but we agree on rescan being safer. Nit interpretation, doesn't matter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #17954 (comment)

I think I meaned because we rely now on wallet last block hash instead of main tip and we may be late from one block, so in my opinion we are less accurate from one block but we agree on rescan being safer. Nit interpretation, doesn't matter.

I think in the case you are talking about the block height/hash/time values in the backup are now more accurate than before because cs_wallet is locked already. So the backup information make will be consistent with the wallet block tip, not the node block tip, in any cases where they are different

@@ -1364,20 +1364,13 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
EnsureWalletIsUnlocked(pwallet);

// Verify all timestamps are present before importing any keys.
const Optional<int> tip_height = locked_chain->getHeight();
now = tip_height ? locked_chain->getBlockMedianTimePast(*tip_height) : 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1f4b604

If #17443 gets first + GetLastBlockTime, you may avoid to call findBlock here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree that caching the last block time would make some of these commits easier.

Copy link
Contributor Author

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review! I pushed a few more commits I think finishing up the wallet rpc code. There are some more changes to come in wallet.cpp after this.

Updated 1f4b604 -> aeba8af (pr/unlock.1 -> pr/unlock.2, compare) with some tweaks to earlier commits and a few new commits extending the PR

re: #17954 (review)

What do you think about caching also last block time at connection ? I think that would make some changes here better by avoiding to uselessly lock the node, even if it's through the interface.

I think it's probably a good idea. It would use some more memory though, and it's unclear if it the change would simplify this PR or not overlap much. I think it's probably something to try out separately.

}
num_blocks = m_wallet->GetLastBlockHeight();
block_time = -1;
m_wallet->chain().findBlock(m_wallet->GetLastBlockHash(), nullptr, &block_time);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cfc9373

As noted in commit, we may have asynchronicity between node and wallet w.r.t block processing. So returned block time may not be the one of last block height. To avoid this we may cache block time to fetch it when needed with GetLastBlockTime. It would also remove some getBlockTime (but not all last time I looked on).

Just to be clear, height and time here should be in sync due to cs_wallet being held above. Could still cache the time though. Commit description is saying how the GUI display should be more up to date after this commit, because the transaction data and num blocks value will be in sync, instead of a higher num blocks being returned with older transaction data

uint256 GetLastBlockHash() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
{
AssertLockHeld(cs_wallet);
assert(m_last_block_processed_height >= 0);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cfc9373

It just occurs to me than this assert and the one in GetLastBlockHeight (than I introduced in 5aacc3e) are unsafe if we don't have a Chain interface from which to query block height at wallet creation (CreateWalletFromFile) but that's something to keep in mind if in the future you can run the wallet without a chain.

Yes, I think these cases would only be hit when running wallet code offline with the bitcoin-wallet tool or something similar. But if we add more offline features more code will have to change to be flexible about missing data

src/wallet/rpcdump.cpp Outdated Show resolved Hide resolved
@@ -564,8 +564,7 @@ UniValue importwallet(const JSONRPCRequest& request)
if (!file.is_open()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
}
Optional<int> tip_height = locked_chain->getHeight();
nTimeBegin = tip_height ? locked_chain->getBlockTime(*tip_height) : 0;
pwallet->chain().findBlock(pwallet->GetLastBlockHash(), nullptr, &nTimeBegin);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

673e0b6

I'm not sure about the commit message, IMO it's less accurate but on the whole make the rescan protection better by starting farther in the past. Anyway, being based on wallet tip or node tip should be safe given the range of TIMESTAMP_WINDOW

Hmm, I'm not sure when it would be less accurate. Are you thinking of a case?

@ryanofsky ryanofsky marked this pull request as ready for review January 22, 2020 22:22
@ryanofsky
Copy link
Contributor Author

Added 3 commits aeba8af -> 60e6595 (pr/unlock.2 -> pr/unlock.3, compare) and removed PR draft status.

I think this is basically done. Combined with #17443 it should remove all calls to interfaces::Chain::Lock methods after wallet loading (#15719 should clean up loading). I'm hoping this PR and #17443 can be merged before #16426 so #16426 can be a little smaller and change wallet behavior less.

@ariard
Copy link
Member

ariard commented Jan 30, 2020

Thanks Russ, will review new changes soon.

I think it's probably a good idea. It would use some more memory though, and it's unclear if it the change would simplify this PR or not overlap much. I think it's probably something to try out separately.

I've a branch doing it, I can try to rebase it on top of this one and squeeze a last one before #16426.

Copy link
Contributor Author

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments below are from last week (they were in pending status because I forgot to submit the github review)

}
num_blocks = m_wallet->GetLastBlockHeight();
block_time = -1;
m_wallet->chain().findBlock(m_wallet->GetLastBlockHash(), nullptr, &block_time);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #17954 (comment)

(Relevant commit is cfc9373)

Even further than cs_wallet, we are still holding cs_main there through the chain lock. When we're going to remove locked_chain we may have asynchronicity due to to height being based on BlockConnected locked by cs_wallet and findBlock locked by cs_main ?

The GUI is asynchronous by design. It just needs to display internally consistent information within a transaction, and be able to determine if the information is fresh or out of date. The num_blocks height here returned to gui is used for that freshness check, so the new value set here should be better than the previous value for that. More ideally, though num_blocks will be replaced by a hash, which #17993 starts to do

@@ -564,8 +564,7 @@ UniValue importwallet(const JSONRPCRequest& request)
if (!file.is_open()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
}
Optional<int> tip_height = locked_chain->getHeight();
nTimeBegin = tip_height ? locked_chain->getBlockTime(*tip_height) : 0;
pwallet->chain().findBlock(pwallet->GetLastBlockHash(), nullptr, &nTimeBegin);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #17954 (comment)

I think I meaned because we rely now on wallet last block hash instead of main tip and we may be late from one block, so in my opinion we are less accurate from one block but we agree on rescan being safer. Nit interpretation, doesn't matter.

I think in the case you are talking about the block height/hash/time values in the backup are now more accurate than before because cs_wallet is locked already. So the backup information make will be consistent with the wallet block tip, not the node block tip, in any cases where they are different

@laanwj laanwj added this to Blockers in High-priority for review Feb 6, 2020
@ryanofsky ryanofsky force-pushed the pr/unlock branch 3 times, most recently from 0d788ae to d2f92a9 Compare February 7, 2020 18:56
ryanofsky added a commit to ryanofsky/bitcoin that referenced this pull request Feb 11, 2020
Poll function was wrongly setting cached height to the current chain height
instead of the chain height at the time of polling.

This bug could cause balances to appear out of date, and was first introduced
bitcoin@a0704a8#diff-2e3836af182cfb375329c3463ffd91f8L117.
Before that commit, there wasn't a problem because cs_main was held during the
poll update.

Currently, the problem should be rare. But if
8937d99 from bitcoin#17954 were merged, the problem
would get worse, because the wrong cachedNumBlocks value would be set if the
wallet was polled in the interval between a block being connected and it
processing the BlockConnected notification.

Thanks to John Newbery <john@johnnewbery.com> for catching this while reviewing
bitcoin#17954.
Copy link
Contributor

@jnewbery jnewbery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed as far as 759e494 wallet: Avoid use of Chain::Lock in rescanblockchain and just have nits so far. I'll try to complete review tomorrow.

src/interfaces/wallet.cpp Show resolved Hide resolved
@@ -1364,20 +1364,13 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
EnsureWalletIsUnlocked(pwallet);

// Verify all timestamps are present before importing any keys.
const Optional<int> tip_height = locked_chain->getHeight();
now = tip_height ? locked_chain->getBlockMedianTimePast(*tip_height) : 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree that caching the last block time would make some of these commits easier.

@@ -145,6 +164,9 @@ class Chain
//! the specified block hash are verified.
virtual double guessVerificationProgress(const uint256& block_hash) = 0;

//! Return true if data is available for the specified blocks.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'specified blocks' is a bit vague. Can you be more precise about what block_hash min_height and max_height mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #17954 (comment)

'specified blocks' is a bit vague. Can you be more precise about what block_hash min_height and max_height mean?

Added description, also made min_height not Optional since nullopt was equivalent to 0


if (!request.params[0].isNull()) {
start_height = request.params[0].get_int();
if (start_height < 0 || !tip_height || start_height > *tip_height) {
if (start_height < 0 || tip_height < 0 || start_height > tip_height) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetLastBlockHeight() can't return a tip_height that's < 0, so I think you can just remove || tip_height < 0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #17954 (comment)

GetLastBlockHeight() can't return a tip_height that's < 0, so I think you can just remove || tip_height < 0

Thanks updated

{
auto locked_chain = pwallet->chain().lock();
Optional<int> tip_height = locked_chain->getHeight();
LOCK(pwallet->cs_wallet);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to hold the wallet lock for this entire block? Does it make sense to call:

WITH_LOCK(pwallet->cs_wallet, pwallet->GetLastBlockHeight());

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #17954 (comment)

Do you need to hold the wallet lock for this entire block? Does it make sense to call:

WITH_LOCK(pwallet->cs_wallet, pwallet->GetLastBlockHeight());

The lock is also needed for the GetLastBlockHash call in the findAncestorByHeight line below. This could do something cleverer to reduce locking, and I'm happy to make changes if there are suggestions, but moving the lock seemed like simplest change that would work.

if (stop_height) {
stop_block = locked_chain->getBlockHash(*stop_height);
}
if (tip_height >= 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I think this is always true, so you can remove this conditional.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #17954 (comment)

Again, I think this is always true, so you can remove this conditional.

Thanks, removed

xdustinface pushed a commit to xdustinface/dash that referenced this pull request Aug 30, 2020
bf36a3c gui: Fix race in WalletModel::pollBalanceChanged (Russell Yanofsky)

Pull request description:

  Poll function was wrongly setting cached height to the current chain height instead of the chain height at the time of polling.

  This bug could cause balances to appear out of date, and was first introduced bitcoin@a0704a8#diff-2e3836af182cfb375329c3463ffd91f8L117. Before that commit, there wasn't a problem because cs_main was held during the poll update.

  Currently, the problem should be rare. But if 8937d99 from bitcoin#17954 were merged, the problem would get worse, because the wrong cachedNumBlocks value would be set if the wallet was polled in the interval between a block being connected and it processing the BlockConnected notification.

  MarcoFalke also points out that a0704a8 could lead to GUI hangs as well, because previously the pollBalanceChanged method, which runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call, but after could make blocking LOCK(cs_main) calls, potentially locking up the GUI.

  Thanks to John Newbery for finding this bug this while reviewing bitcoin#17954.

ACKs for top commit:
  Empact:
    utACK bitcoin@bf36a3c
  jonasschnelli:
    utACK bf36a3c

Tree-SHA512: 1f4f229fa70a6d1fcf7be3806dca3252e86bc1755168fb421258389eb95aae67f863cb1216e6dc086b596c33560d1136215a4c87b5ff890abc8baaa3333b47f4
xdustinface pushed a commit to xdustinface/dash that referenced this pull request Aug 30, 2020
bf36a3c gui: Fix race in WalletModel::pollBalanceChanged (Russell Yanofsky)

Pull request description:

  Poll function was wrongly setting cached height to the current chain height instead of the chain height at the time of polling.

  This bug could cause balances to appear out of date, and was first introduced bitcoin@a0704a8#diff-2e3836af182cfb375329c3463ffd91f8L117. Before that commit, there wasn't a problem because cs_main was held during the poll update.

  Currently, the problem should be rare. But if 8937d99 from bitcoin#17954 were merged, the problem would get worse, because the wrong cachedNumBlocks value would be set if the wallet was polled in the interval between a block being connected and it processing the BlockConnected notification.

  MarcoFalke also points out that a0704a8 could lead to GUI hangs as well, because previously the pollBalanceChanged method, which runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call, but after could make blocking LOCK(cs_main) calls, potentially locking up the GUI.

  Thanks to John Newbery for finding this bug this while reviewing bitcoin#17954.

ACKs for top commit:
  Empact:
    utACK bitcoin@bf36a3c
  jonasschnelli:
    utACK bf36a3c

Tree-SHA512: 1f4f229fa70a6d1fcf7be3806dca3252e86bc1755168fb421258389eb95aae67f863cb1216e6dc086b596c33560d1136215a4c87b5ff890abc8baaa3333b47f4
xdustinface pushed a commit to xdustinface/dash that referenced this pull request Aug 31, 2020
bf36a3c gui: Fix race in WalletModel::pollBalanceChanged (Russell Yanofsky)

Pull request description:

  Poll function was wrongly setting cached height to the current chain height instead of the chain height at the time of polling.

  This bug could cause balances to appear out of date, and was first introduced bitcoin@a0704a8#diff-2e3836af182cfb375329c3463ffd91f8L117. Before that commit, there wasn't a problem because cs_main was held during the poll update.

  Currently, the problem should be rare. But if 8937d99 from bitcoin#17954 were merged, the problem would get worse, because the wrong cachedNumBlocks value would be set if the wallet was polled in the interval between a block being connected and it processing the BlockConnected notification.

  MarcoFalke also points out that a0704a8 could lead to GUI hangs as well, because previously the pollBalanceChanged method, which runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call, but after could make blocking LOCK(cs_main) calls, potentially locking up the GUI.

  Thanks to John Newbery for finding this bug this while reviewing bitcoin#17954.

ACKs for top commit:
  Empact:
    utACK bitcoin@bf36a3c
  jonasschnelli:
    utACK bf36a3c

Tree-SHA512: 1f4f229fa70a6d1fcf7be3806dca3252e86bc1755168fb421258389eb95aae67f863cb1216e6dc086b596c33560d1136215a4c87b5ff890abc8baaa3333b47f4
xdustinface pushed a commit to xdustinface/dash that referenced this pull request Sep 27, 2020
bf36a3c gui: Fix race in WalletModel::pollBalanceChanged (Russell Yanofsky)

Pull request description:

  Poll function was wrongly setting cached height to the current chain height instead of the chain height at the time of polling.

  This bug could cause balances to appear out of date, and was first introduced bitcoin@a0704a8#diff-2e3836af182cfb375329c3463ffd91f8L117. Before that commit, there wasn't a problem because cs_main was held during the poll update.

  Currently, the problem should be rare. But if 8937d99 from bitcoin#17954 were merged, the problem would get worse, because the wrong cachedNumBlocks value would be set if the wallet was polled in the interval between a block being connected and it processing the BlockConnected notification.

  MarcoFalke also points out that a0704a8 could lead to GUI hangs as well, because previously the pollBalanceChanged method, which runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call, but after could make blocking LOCK(cs_main) calls, potentially locking up the GUI.

  Thanks to John Newbery for finding this bug this while reviewing bitcoin#17954.

ACKs for top commit:
  Empact:
    utACK bitcoin@bf36a3c
  jonasschnelli:
    utACK bf36a3c

Tree-SHA512: 1f4f229fa70a6d1fcf7be3806dca3252e86bc1755168fb421258389eb95aae67f863cb1216e6dc086b596c33560d1136215a4c87b5ff890abc8baaa3333b47f4
xdustinface pushed a commit to xdustinface/dash that referenced this pull request Sep 29, 2020
bf36a3c gui: Fix race in WalletModel::pollBalanceChanged (Russell Yanofsky)

Pull request description:

  Poll function was wrongly setting cached height to the current chain height instead of the chain height at the time of polling.

  This bug could cause balances to appear out of date, and was first introduced bitcoin@a0704a8#diff-2e3836af182cfb375329c3463ffd91f8L117. Before that commit, there wasn't a problem because cs_main was held during the poll update.

  Currently, the problem should be rare. But if 8937d99 from bitcoin#17954 were merged, the problem would get worse, because the wrong cachedNumBlocks value would be set if the wallet was polled in the interval between a block being connected and it processing the BlockConnected notification.

  MarcoFalke also points out that a0704a8 could lead to GUI hangs as well, because previously the pollBalanceChanged method, which runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call, but after could make blocking LOCK(cs_main) calls, potentially locking up the GUI.

  Thanks to John Newbery for finding this bug this while reviewing bitcoin#17954.

ACKs for top commit:
  Empact:
    utACK bitcoin@bf36a3c
  jonasschnelli:
    utACK bf36a3c

Tree-SHA512: 1f4f229fa70a6d1fcf7be3806dca3252e86bc1755168fb421258389eb95aae67f863cb1216e6dc086b596c33560d1136215a4c87b5ff890abc8baaa3333b47f4
xdustinface pushed a commit to xdustinface/dash that referenced this pull request Sep 29, 2020
bf36a3c gui: Fix race in WalletModel::pollBalanceChanged (Russell Yanofsky)

Pull request description:

  Poll function was wrongly setting cached height to the current chain height instead of the chain height at the time of polling.

  This bug could cause balances to appear out of date, and was first introduced bitcoin@a0704a8#diff-2e3836af182cfb375329c3463ffd91f8L117. Before that commit, there wasn't a problem because cs_main was held during the poll update.

  Currently, the problem should be rare. But if 8937d99 from bitcoin#17954 were merged, the problem would get worse, because the wrong cachedNumBlocks value would be set if the wallet was polled in the interval between a block being connected and it processing the BlockConnected notification.

  MarcoFalke also points out that a0704a8 could lead to GUI hangs as well, because previously the pollBalanceChanged method, which runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call, but after could make blocking LOCK(cs_main) calls, potentially locking up the GUI.

  Thanks to John Newbery for finding this bug this while reviewing bitcoin#17954.

ACKs for top commit:
  Empact:
    utACK bitcoin@bf36a3c
  jonasschnelli:
    utACK bf36a3c

Tree-SHA512: 1f4f229fa70a6d1fcf7be3806dca3252e86bc1755168fb421258389eb95aae67f863cb1216e6dc086b596c33560d1136215a4c87b5ff890abc8baaa3333b47f4
xdustinface pushed a commit to xdustinface/dash that referenced this pull request Oct 2, 2020
bf36a3c gui: Fix race in WalletModel::pollBalanceChanged (Russell Yanofsky)

Pull request description:

  Poll function was wrongly setting cached height to the current chain height instead of the chain height at the time of polling.

  This bug could cause balances to appear out of date, and was first introduced bitcoin@a0704a8#diff-2e3836af182cfb375329c3463ffd91f8L117. Before that commit, there wasn't a problem because cs_main was held during the poll update.

  Currently, the problem should be rare. But if 8937d99 from bitcoin#17954 were merged, the problem would get worse, because the wrong cachedNumBlocks value would be set if the wallet was polled in the interval between a block being connected and it processing the BlockConnected notification.

  MarcoFalke also points out that a0704a8 could lead to GUI hangs as well, because previously the pollBalanceChanged method, which runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call, but after could make blocking LOCK(cs_main) calls, potentially locking up the GUI.

  Thanks to John Newbery for finding this bug this while reviewing bitcoin#17954.

ACKs for top commit:
  Empact:
    utACK bitcoin@bf36a3c
  jonasschnelli:
    utACK bf36a3c

Tree-SHA512: 1f4f229fa70a6d1fcf7be3806dca3252e86bc1755168fb421258389eb95aae67f863cb1216e6dc086b596c33560d1136215a4c87b5ff890abc8baaa3333b47f4
xdustinface pushed a commit to xdustinface/dash that referenced this pull request Oct 2, 2020
bf36a3c gui: Fix race in WalletModel::pollBalanceChanged (Russell Yanofsky)

Pull request description:

  Poll function was wrongly setting cached height to the current chain height instead of the chain height at the time of polling.

  This bug could cause balances to appear out of date, and was first introduced bitcoin@a0704a8#diff-2e3836af182cfb375329c3463ffd91f8L117. Before that commit, there wasn't a problem because cs_main was held during the poll update.

  Currently, the problem should be rare. But if 8937d99 from bitcoin#17954 were merged, the problem would get worse, because the wrong cachedNumBlocks value would be set if the wallet was polled in the interval between a block being connected and it processing the BlockConnected notification.

  MarcoFalke also points out that a0704a8 could lead to GUI hangs as well, because previously the pollBalanceChanged method, which runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call, but after could make blocking LOCK(cs_main) calls, potentially locking up the GUI.

  Thanks to John Newbery for finding this bug this while reviewing bitcoin#17954.

ACKs for top commit:
  Empact:
    utACK bitcoin@bf36a3c
  jonasschnelli:
    utACK bf36a3c

Tree-SHA512: 1f4f229fa70a6d1fcf7be3806dca3252e86bc1755168fb421258389eb95aae67f863cb1216e6dc086b596c33560d1136215a4c87b5ff890abc8baaa3333b47f4
xdustinface pushed a commit to xdustinface/dash that referenced this pull request Oct 5, 2020
bf36a3c gui: Fix race in WalletModel::pollBalanceChanged (Russell Yanofsky)

Pull request description:

  Poll function was wrongly setting cached height to the current chain height instead of the chain height at the time of polling.

  This bug could cause balances to appear out of date, and was first introduced bitcoin@a0704a8#diff-2e3836af182cfb375329c3463ffd91f8L117. Before that commit, there wasn't a problem because cs_main was held during the poll update.

  Currently, the problem should be rare. But if 8937d99 from bitcoin#17954 were merged, the problem would get worse, because the wrong cachedNumBlocks value would be set if the wallet was polled in the interval between a block being connected and it processing the BlockConnected notification.

  MarcoFalke also points out that a0704a8 could lead to GUI hangs as well, because previously the pollBalanceChanged method, which runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call, but after could make blocking LOCK(cs_main) calls, potentially locking up the GUI.

  Thanks to John Newbery for finding this bug this while reviewing bitcoin#17954.

ACKs for top commit:
  Empact:
    utACK bitcoin@bf36a3c
  jonasschnelli:
    utACK bf36a3c

Tree-SHA512: 1f4f229fa70a6d1fcf7be3806dca3252e86bc1755168fb421258389eb95aae67f863cb1216e6dc086b596c33560d1136215a4c87b5ff890abc8baaa3333b47f4
xdustinface pushed a commit to xdustinface/dash that referenced this pull request Oct 5, 2020
bf36a3c gui: Fix race in WalletModel::pollBalanceChanged (Russell Yanofsky)

Pull request description:

  Poll function was wrongly setting cached height to the current chain height instead of the chain height at the time of polling.

  This bug could cause balances to appear out of date, and was first introduced bitcoin@a0704a8#diff-2e3836af182cfb375329c3463ffd91f8L117. Before that commit, there wasn't a problem because cs_main was held during the poll update.

  Currently, the problem should be rare. But if 8937d99 from bitcoin#17954 were merged, the problem would get worse, because the wrong cachedNumBlocks value would be set if the wallet was polled in the interval between a block being connected and it processing the BlockConnected notification.

  MarcoFalke also points out that a0704a8 could lead to GUI hangs as well, because previously the pollBalanceChanged method, which runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call, but after could make blocking LOCK(cs_main) calls, potentially locking up the GUI.

  Thanks to John Newbery for finding this bug this while reviewing bitcoin#17954.

ACKs for top commit:
  Empact:
    utACK bitcoin@bf36a3c
  jonasschnelli:
    utACK bf36a3c

Tree-SHA512: 1f4f229fa70a6d1fcf7be3806dca3252e86bc1755168fb421258389eb95aae67f863cb1216e6dc086b596c33560d1136215a4c87b5ff890abc8baaa3333b47f4
deadalnix pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 11, 2020
…k data

Summary:
FoundBlock class allows interfaces::Chain::findBlock to return more block
information without having lots of optional output parameters. FoundBlock class
is also used by other chain methods in upcoming commits.

There is mostly no change in behavior. Only exception is
CWallet::RescanFromTime now throwing NonFatalCheckError instead of
std::logic_error.

This is part [1/12] of Core [[bitcoin/bitcoin#17954 | PR17954]] : bitcoin/bitcoin@bf30cd4

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7864
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 11, 2020
Summary:
This is a step toward removing the Chain::Lock class and reducing cs_main
locking.

It also helps ensure the GUI display stays up to date in the case where the
node chain height runs ahead of wallet last block processed height.

This is part [2/12] of Core [[bitcoin/bitcoin#17954 | PR17954]] : bitcoin/bitcoin@f6da44c

Depends on D7864

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7865
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 11, 2020
Summary:
This is a step toward removing the Chain::Lock class and reducing cs_main
locking.

This change doesn't affect behavior.

This is part [3/12] of Core [[bitcoin/bitcoin#17954 | PR17954]] : bitcoin/bitcoin@ade5f87

Depends on D7865

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7866
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 11, 2020
Summary:
This is a step toward removing the Chain::Lock class and reducing cs_main
locking.

This change only affects behavior in the case where wallet last block processed
falls behind the chain tip, in which case the "Block not found in chain" error
will be stricter and not allow importing data from a blocks between the wallet
last processed tip and the current node tip.

This is part [4/12] of Core [[bitcoin/bitcoin#17954 | PR17954]] : bitcoin/bitcoin@c1694ce

Depends on D7866

Test Plan:
  ninja all check

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7867
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 11, 2020
Summary:
This is a step toward removing the Chain::Lock class and reducing cs_main
locking.

This change only affects behavior in the case where wallet last block processed
falls behind the chain tip, in which case it will use more accurate backup and
rescan timestamps.

This is part [5/12] of Core [[bitcoin/bitcoin#17954 | PR17954]] : bitcoin/bitcoin@25a9fcf

Depends on D7867

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7868
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 11, 2020
Summary:
This is a step toward removing the Chain::Lock class and reducing cs_main
locking.

This change only affects behavior in the case where wallet last block processed
falls behind the chain tip, in which case it may use a more accurate rescan
time.

This is part [6/12] of Core [[bitcoin/bitcoin#17954 | PR17954]] : bitcoin/bitcoin@bc96a9b

Depends on D7868

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7869
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 11, 2020
Summary:
This is a step toward removing the Chain::Lock class and reducing cs_main
locking.

This change only affects behavior in the case where wallet last block processed
falls behind the chain tip. Previously listsinceblock might not have returned
all transactions up to the claimed "lastblock" value in this case, resulting in
race conditions and potentially missing transactions in cases where
listsinceblock was called in a loop like
bitcoin/bitcoin#14338 (comment)

This is part [7/12] of Core [[bitcoin/bitcoin#17954 | PR17954]] : bitcoin/bitcoin@f7ba881

Depends on D7869

Test Plan:
  ninja all check

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7870
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 11, 2020
Summary:
This is a step toward removing the Chain::Lock class and reducing cs_main
locking.

This change has no effect on behavior.

This is part [8/12] of Core [[bitcoin/bitcoin#17954 | PR17954]] : bitcoin/bitcoin@3cb85ac

Depends on D7870

Test Plan:
  ninja all check

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7871
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 11, 2020
Summary:
This is a step toward removing the Chain::Lock class and reducing cs_main
locking.

This change only affects behavior in the case where wallet last block processed
falls behind the chain tip. The rescanblockchain error height error checking
will just be stricter in this case and only accept values up to the last
processed height

This is part [9/12] of Core [[bitcoin/bitcoin#17954 | PR17954]] : bitcoin/bitcoin@1be8ff2

Depends on D7871

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7872
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 11, 2020
Summary:
This is a step toward removing the Chain::Lock class and reducing cs_main
locking.

This change affects behavior in a few small ways.

- If there's no max_height specified, percentage progress is measured ending at
  wallet last processed block instead of node tip

- More consistent error reporting: Early check to see if start_block is on the
  active chain is removed, so start_block is always read and the triggers an
  error if it's unavailable

This is part [10/12] of Core [[bitcoin/bitcoin#17954 | PR17954]] : bitcoin/bitcoin@c0d07dc

Depends on D7872

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Subscribers: Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7873
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 11, 2020
Summary:
This is a step toward removing the Chain::Lock class and reducing cs_main
locking.

This change only affects behavior in the case where wallet last block processed
falls behind the chain tip, where it may set a different lock time.

This is part [11/12] of Core [[bitcoin/bitcoin#17954 | PR17954]] : bitcoin/bitcoin@e958ff9

Depends on D7873

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7874
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 11, 2020
Summary:
This is a step toward removing the Chain::Lock class and reducing cs_main
locking.

This change only affects behavior in the case where wallet last block processed
falls behind the chain tip, where it will treat the last block processed as the
current tip.

This is part [12/12] of Core [[bitcoin/bitcoin#17954 | PR17954]] : bitcoin/bitcoin@4897340

Depends on D7874

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7875
xdustinface pushed a commit to xdustinface/dash that referenced this pull request Oct 14, 2020
bf36a3c gui: Fix race in WalletModel::pollBalanceChanged (Russell Yanofsky)

Pull request description:

  Poll function was wrongly setting cached height to the current chain height instead of the chain height at the time of polling.

  This bug could cause balances to appear out of date, and was first introduced bitcoin@a0704a8#diff-2e3836af182cfb375329c3463ffd91f8L117. Before that commit, there wasn't a problem because cs_main was held during the poll update.

  Currently, the problem should be rare. But if 8937d99 from bitcoin#17954 were merged, the problem would get worse, because the wrong cachedNumBlocks value would be set if the wallet was polled in the interval between a block being connected and it processing the BlockConnected notification.

  MarcoFalke also points out that a0704a8 could lead to GUI hangs as well, because previously the pollBalanceChanged method, which runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call, but after could make blocking LOCK(cs_main) calls, potentially locking up the GUI.

  Thanks to John Newbery for finding this bug this while reviewing bitcoin#17954.

ACKs for top commit:
  Empact:
    utACK bitcoin@bf36a3c
  jonasschnelli:
    utACK bf36a3c

Tree-SHA512: 1f4f229fa70a6d1fcf7be3806dca3252e86bc1755168fb421258389eb95aae67f863cb1216e6dc086b596c33560d1136215a4c87b5ff890abc8baaa3333b47f4
van-orton pushed a commit to BitgesellOfficial/bitgesell that referenced this pull request Oct 30, 2020
Poll function was wrongly setting cached height to the current chain height
instead of the chain height at the time of polling.

This bug could cause balances to appear out of date, and was first introduced
bitcoin/bitcoin@a0704a8#r378452145
Before that commit, there wasn't a problem because cs_main was held during the
poll update.

Currently, the problem should be rare. But if
8937d99ce81a27ae5e1012a28323c0e26d89c50b from #17954 were merged, the problem
would get worse, because the wrong cachedNumBlocks value would be set if the
wallet was polled in the interval between a block being connected and it
processing the BlockConnected notification.

MarcoFalke <falke.marco@gmail.com> also points out that a0704a8996b could lead
to GUI hangs as well, because previously the pollBalanceChanged method, which
runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call,
but after could make blocking LOCK(cs_main) calls, potentially locking up the
GUI.

Thanks to John Newbery <john@johnnewbery.com> for finding this bug this while
reviewing bitcoin/bitcoin#17954.
sidhujag pushed a commit to syscoin-core/syscoin that referenced this pull request Nov 10, 2020
Poll function was wrongly setting cached height to the current chain height
instead of the chain height at the time of polling.

This bug could cause balances to appear out of date, and was first introduced
bitcoin@a0704a8#r378452145
Before that commit, there wasn't a problem because cs_main was held during the
poll update.

Currently, the problem should be rare. But if
8937d99 from bitcoin#17954 were merged, the problem
would get worse, because the wrong cachedNumBlocks value would be set if the
wallet was polled in the interval between a block being connected and it
processing the BlockConnected notification.

MarcoFalke <falke.marco@gmail.com> also points out that a0704a8 could lead
to GUI hangs as well, because previously the pollBalanceChanged method, which
runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call,
but after could make blocking LOCK(cs_main) calls, potentially locking up the
GUI.

Thanks to John Newbery <john@johnnewbery.com> for finding this bug this while
reviewing bitcoin#17954.
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Jan 2, 2021
Summary:
Poll function was wrongly setting cached height to the current chain height
instead of the chain height at the time of polling.

This bug could cause balances to appear out of date, and was first introduced
bitcoin/bitcoin@a0704a8#r378452145
Before that commit, there wasn't a problem because cs_main was held during the
poll update.

Currently, the problem should be rare. But if
8937d99ce81a27ae5e1012a28323c0e26d89c50b from [[bitcoin/bitcoin#17954 | PR17954]] were merged, the problem
would get worse, because the wrong cachedNumBlocks value would be set if the
wallet was polled in the interval between a block being connected and it
processing the BlockConnected notification.

MarcoFalke <falke.marco@gmail.com> also points out that a0704a8 could lead
to GUI hangs as well, because previously the pollBalanceChanged method, which
runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call,
but after could make blocking LOCK(cs_main) calls, potentially locking up the
GUI.

Thanks to John Newbery <john@johnnewbery.com> for finding this bug this while
reviewing [[bitcoin/bitcoin#17954 | PR17954]].

This is a backport of Core [[bitcoin/bitcoin#18123 | PR18123]]

Test Plan: `ninja && src/qt/bitcoin-qt`

Reviewers: #bitcoin_abc, deadalnix

Reviewed By: #bitcoin_abc, deadalnix

Differential Revision: https://reviews.bitcoinabc.org/D8764
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Jan 15, 2021
Summary:
This prevent regressions n comments such as the date of the dump no longer being human readable (bitcoin/bitcoin#17954 (comment))

This is a backport of Core [[bitcoin/bitcoin#18597 | PR18597]]

Test Plan: test/functional/test_runner.py wallet_dump

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D8923
backpacker69 pushed a commit to peercoin/peercoin that referenced this pull request Mar 28, 2021
Poll function was wrongly setting cached height to the current chain height
instead of the chain height at the time of polling.

This bug could cause balances to appear out of date, and was first introduced
bitcoin/bitcoin@a0704a8#r378452145
Before that commit, there wasn't a problem because cs_main was held during the
poll update.

Currently, the problem should be rare. But if
8937d99ce81a27ae5e1012a28323c0e26d89c50b from #17954 were merged, the problem
would get worse, because the wrong cachedNumBlocks value would be set if the
wallet was polled in the interval between a block being connected and it
processing the BlockConnected notification.

MarcoFalke <falke.marco@gmail.com> also points out that a0704a8 could lead
to GUI hangs as well, because previously the pollBalanceChanged method, which
runs on the GUI thread, would only make a nonblocking TRY_LOCK(cs_main) call,
but after could make blocking LOCK(cs_main) calls, potentially locking up the
GUI.

Thanks to John Newbery <john@johnnewbery.com> for finding this bug this while
reviewing bitcoin/bitcoin#17954.
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet