Skip to content

Conversation

ryanofsky
Copy link
Contributor

@ryanofsky ryanofsky commented Feb 4, 2020

Make LegacyScriptPubKeyMan::CanProvide method able to recognize p2sh scripts when the redeem script is present in the mapScripts map without the p2sh script also having to be added to the mapScripts map. This restores behavior prior to #17261, which I think broke backwards compatibility with old wallet files by no longer treating addresses created by addmultisigaddress calls before #17261 as solvable.

The reason why tests didn't fail with the CanProvide implementation in #17261 is because of a workaround added in 4a7e43e "Store p2sh scripts in AddAndGetDestinationForScript", which masked the problem for new addmultisigaddress RPC calls without fixing it for multisig addresses already created in old wallet files.

This change adds a lot of comments and allows reverting commit 4a7e43e "Store p2sh scripts in AddAndGetDestinationForScript", so the AddAndGetDestinationForScript() function, CanProvide() method, and mapScripts map should all be more comprehensible

@achow101
Copy link
Member

ACK 891b0ee

Confirms this fixes #18075

@Sjors
Copy link
Member

Sjors commented Feb 11, 2020

Tested ACK 891b0ee. Thanks for adding all the clarifications and scriptpubkeyman_tests.

So IIUC the reason we didn't see addresses added with addmultisigaddress in older wallets, is that AddAndGetMultisigDestination calls AddAndGetDestinationForScript which in turn called AddCScript on the multisig p2sh script, but not the public keys and private keys. Without those keys it's considered ISMINE_NO. When CanProvide looks at the P2SH address, it calls IsMine which calls IsMineInner with recurse_scripthash = true. Starting at the TOP level IsMineInner it identifies the address as TX_SCRIPTHASH. It would then try to find the script and run it through IsMineInner at the IsMineSigVersion::P2SH level. There it would be recognised as a TX_MULTISIG, which requires all (private) keys, but we have none (or maybe one in a more realistic wallet).

I'm still not entirely clear what the workaround in 4a7e43e did other than "pass the tests", but it clearly doesn't solve the above, since it still doesn't add (private) keys.

In this PR CanProvide uses recurse_scripthash = false in IsMineInner, and we modified that to consider a TX_SCRIPTHASH or TX_WITNESS_V0_SCRIPTHASH to be SPENDABLE.

Meanwhile the RPC uses pwallet->IsMine(dest) which uses the original "need all keys" behaviour under recurse_scripthash = true. So we slightly expand what's covered by CanProvide without adding stuff to the wallet.

@sipa does this many any sense?

@maflcko
Copy link
Member

maflcko commented Feb 12, 2020

Would be nice to rebase and cherry-pick Sjors/bitcoin@bacf559 into this

ryanofsky and others added 3 commits February 12, 2020 11:48
Make LegacyScriptPubKeyMan::CanProvide method able to recognize p2sh scripts
when the redeem script is present in the mapScripts map without the p2sh script
also having to be added to the mapScripts map. This restores behavior prior to
bitcoin#17261, which I think broke backwards
compatibility with old wallet files by no longer treating addresses created by
`addmultisigaddress` calls before bitcoin#17261 as solvable.

The reason why tests didn't fail with the CanProvide implementation in bitcoin#17261
is because of a workaround added in 4a7e43e
"Store p2sh scripts in AddAndGetDestinationForScript", which masked the problem
for new `addmultisigaddress` RPC calls without fixing it for multisig addresses
already created in old wallet files.

This change adds a lot of comments and allows reverting commit
4a7e43e "Store p2sh scripts in
AddAndGetDestinationForScript", so the AddAndGetDestinationForScript() function,
CanProvide() method, and mapScripts map should all be more comprehensible
@ryanofsky
Copy link
Contributor Author

Rebased 891b0ee -> a304a36 (pr/provide.1 -> pr/provide.2, compare) on top of #12134, also editing the mapScripts comment and cherry-picking Sjors' test commit

Thank you Sjors for the great test case and bug description in #18067 (comment)! I'm really glad to see the test framework in #12134 merged, too.

re: #18067 (comment)

I'm still not entirely clear what the workaround in 4a7e43e did other than "pass the tests", but it clearly doesn't solve the above, since it still doesn't add (private) keys.

The reason why the workaround in 4a7e43e was able to mask the problem is because of this condition in LegacyScriptPubKeyMan::CanProvide:

} else if (HaveCScript(CScriptID(script))) {
// We can still provide some stuff if we have the script, but IsMine failed because we don't have keys
return true;

The first commit in this PR drops this condition so it is breaking the workaround at the same time as making the workaround unnecessary by fixing the bug.

I was a little on the fence about whether to remove this condition, but I think it's better not to have it, so CanProvide just wraps the IsMine and ProduceSignature code instead of trying to be its own third IsMine implementation.

@Sjors
Copy link
Member

Sjors commented Feb 12, 2020

re-ACK a304a36 (rebase, slight text changes and my test)

@achow101
Copy link
Member

re-ACK a304a36

Copy link
Contributor

@meshcollider meshcollider left a comment

Choose a reason for hiding this comment

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

utACK a304a36

meshcollider added a commit that referenced this pull request Feb 19, 2020
…t recognition

a304a36 Revert "Store p2sh scripts in AddAndGetDestinationForScript" (Russell Yanofsky)
eb7d8a5 [test] check for addmultisigaddress regression (Sjors Provoost)
005f8a9 wallet: Improve LegacyScriptPubKeyMan::CanProvide script recognition (Russell Yanofsky)

Pull request description:

  Make `LegacyScriptPubKeyMan::CanProvide` method able to recognize p2sh scripts when the redeem script is present in the `mapScripts` map without the p2sh script also having to be added to the `mapScripts` map. This restores behavior prior to #17261, which I think broke backwards compatibility with old wallet files by no longer treating addresses created by `addmultisigaddress` calls before #17261 as solvable.

  The reason why tests didn't fail with the CanProvide implementation in #17261 is because of a workaround added in 4a7e43e "Store p2sh scripts in AddAndGetDestinationForScript", which masked the problem for new `addmultisigaddress` RPC calls without fixing it for multisig addresses already created in old wallet files.

  This change adds a lot of comments and allows reverting commit 4a7e43e "Store p2sh scripts in AddAndGetDestinationForScript", so the `AddAndGetDestinationForScript()` function, `CanProvide()` method, and `mapScripts` map should all be more comprehensible

ACKs for top commit:
  Sjors:
    re-ACK a304a36 (rebase, slight text changes and my test)
  achow101:
    re-ACK a304a36
  meshcollider:
    utACK a304a36

Tree-SHA512: 03b625220c49684c376a8062d7646aeba0e5bfe043f977dc7dc357a6754627d594e070e4d458d12d2291888405d94c1dbe08c7787c318374cedd5755e724fb6e
@meshcollider meshcollider merged commit a304a36 into bitcoin:master Feb 19, 2020
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Feb 19, 2020
…e script recognition

a304a36 Revert "Store p2sh scripts in AddAndGetDestinationForScript" (Russell Yanofsky)
eb7d8a5 [test] check for addmultisigaddress regression (Sjors Provoost)
005f8a9 wallet: Improve LegacyScriptPubKeyMan::CanProvide script recognition (Russell Yanofsky)

Pull request description:

  Make `LegacyScriptPubKeyMan::CanProvide` method able to recognize p2sh scripts when the redeem script is present in the `mapScripts` map without the p2sh script also having to be added to the `mapScripts` map. This restores behavior prior to bitcoin#17261, which I think broke backwards compatibility with old wallet files by no longer treating addresses created by `addmultisigaddress` calls before bitcoin#17261 as solvable.

  The reason why tests didn't fail with the CanProvide implementation in bitcoin#17261 is because of a workaround added in 4a7e43e "Store p2sh scripts in AddAndGetDestinationForScript", which masked the problem for new `addmultisigaddress` RPC calls without fixing it for multisig addresses already created in old wallet files.

  This change adds a lot of comments and allows reverting commit 4a7e43e "Store p2sh scripts in AddAndGetDestinationForScript", so the `AddAndGetDestinationForScript()` function, `CanProvide()` method, and `mapScripts` map should all be more comprehensible

ACKs for top commit:
  Sjors:
    re-ACK a304a36 (rebase, slight text changes and my test)
  achow101:
    re-ACK a304a36
  meshcollider:
    utACK a304a36

Tree-SHA512: 03b625220c49684c376a8062d7646aeba0e5bfe043f977dc7dc357a6754627d594e070e4d458d12d2291888405d94c1dbe08c7787c318374cedd5755e724fb6e
sidhujag pushed a commit to syscoin-core/syscoin that referenced this pull request Nov 10, 2020
…e script recognition

a304a36 Revert "Store p2sh scripts in AddAndGetDestinationForScript" (Russell Yanofsky)
eb7d8a5 [test] check for addmultisigaddress regression (Sjors Provoost)
005f8a9 wallet: Improve LegacyScriptPubKeyMan::CanProvide script recognition (Russell Yanofsky)

Pull request description:

  Make `LegacyScriptPubKeyMan::CanProvide` method able to recognize p2sh scripts when the redeem script is present in the `mapScripts` map without the p2sh script also having to be added to the `mapScripts` map. This restores behavior prior to bitcoin#17261, which I think broke backwards compatibility with old wallet files by no longer treating addresses created by `addmultisigaddress` calls before bitcoin#17261 as solvable.

  The reason why tests didn't fail with the CanProvide implementation in bitcoin#17261 is because of a workaround added in 4a7e43e "Store p2sh scripts in AddAndGetDestinationForScript", which masked the problem for new `addmultisigaddress` RPC calls without fixing it for multisig addresses already created in old wallet files.

  This change adds a lot of comments and allows reverting commit 4a7e43e "Store p2sh scripts in AddAndGetDestinationForScript", so the `AddAndGetDestinationForScript()` function, `CanProvide()` method, and `mapScripts` map should all be more comprehensible

ACKs for top commit:
  Sjors:
    re-ACK a304a36 (rebase, slight text changes and my test)
  achow101:
    re-ACK a304a36
  meshcollider:
    utACK a304a36

Tree-SHA512: 03b625220c49684c376a8062d7646aeba0e5bfe043f977dc7dc357a6754627d594e070e4d458d12d2291888405d94c1dbe08c7787c318374cedd5755e724fb6e
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Feb 2, 2021
…ript recognition

Summary:
a304a3632f0437f4d0f04589a2200e2da91624a7 Revert "Store p2sh scripts in AddAndGetDestinationForScript" (Russell Yanofsky)
eb7d8a5b07e89133a5fb465ad1b793362e7439f7 [test] check for addmultisigaddress regression (Sjors Provoost)
005f8a92ccb5bc10c8daa106d75e1c21390461d3 wallet: Improve LegacyScriptPubKeyMan::CanProvide script recognition (Russell Yanofsky)

Pull request description:

  Make `LegacyScriptPubKeyMan::CanProvide` method able to recognize p2sh scripts when the redeem script is present in the `mapScripts` map without the p2sh script also having to be added to the `mapScripts` map. This restores behavior prior to #17261, which I think broke backwards compatibility with old wallet files by no longer treating addresses created by `addmultisigaddress` calls before #17261 as solvable.

  The reason why tests didn't fail with the CanProvide implementation in #17261 is because of a workaround added in 4a7e43e8460127a40a7895519587399feff3b682 "Store p2sh scripts in AddAndGetDestinationForScript", which masked the problem for new `addmultisigaddress` RPC calls without fixing it for multisig addresses already created in old wallet files.

  This change adds a lot of comments and allows reverting commit 4a7e43e8460127a40a7895519587399feff3b682 "Store p2sh scripts in AddAndGetDestinationForScript", so the `AddAndGetDestinationForScript()` function, `CanProvide()` method, and `mapScripts` map should all be more comprehensible

---

Backport of Core [[bitcoin/bitcoin#18067 | PR18067]]

Test Plan:
  ninja all check check-functional

Reviewers: #bitcoin_abc, PiRK

Reviewed By: #bitcoin_abc, PiRK

Subscribers: PiRK

Differential Revision: https://reviews.bitcoinabc.org/D9115
@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.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants