Replace wallet bump_fee command --send_all with new --shrink option - #45

Merged
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall
Nov 2, 2021
Merged

Replace wallet bump_fee command --send_all with new --shrink option#45
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall

Conversation

@notmandatory

@notmandatorynotmandatory commented Oct 7, 2021

Copy link
Copy Markdown
Member

Description

Replace wallet bump_fee command --send_all with new --shrink ADDRESS option to reduce the output amount for the specified address to increase RBF transaction fee.

Notes to the reviewers

This new option is primarily needed when bumping the fee of a send_all transaction or any other transaction that doesn't have a change output that can be reduced to bump the fee on the new RBF transaction.

Steps I used to test

  1. create wallet with two utxos
  2. create and broadcast send_all tx with rbf enabled and 1 sat/vbyte fee back to testnet faucet
  3. create and broadcast bump_fee rbf for above tx with 7 sat/vbyte fee and shrinking the testnet faucet address

https://mempool.space/testnet/tx/e35892843875e084f39c5285ee6f522764210351f78cd89305a49efbf4bfea48

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@notmandatorynotmandatory mentioned this pull request Oct 8, 2021
3 tasks

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah right. We could get the scriptpubkey from specifying the address. And it seems bdk internal doesn't care if the address belongs to us or not, while shrinking.

But I am thinking, doesn't this opens an attack vector in bdk wallet code?

For example I can construct a transaction to a merchant, with very low fee. He will see money coming into his wallet (as many doesn't wait for confirmations). Then half an hour later after leaving the shop, I can then bumpfee to reduce the merchant's output to 0.

The cost of this attack is basically zero, because the attacker will not loose any more money, than he already paid for. He has already spent his input and will get the change back.

Note: This behavior of not to decrease external recipient's amount is not enforced by the bitcoin protocol (it can't be). It is an wallet level feature. And I think wallets implementing bumpfee will need to account for that in their impls.

For reference, heres the doc for bumpfee behaviour of the Bitcoin Core wallet. It doesn't allow reducing external outputs, and if there isn't any change ouput in a tx, the wallet will proactively add one.

https://developer.bitcoin.org/reference/rpc/bumpfee.html

This where the change selection logic happens in bitcoin core wallet.
https://github.com/bitcoin/bitcoin/blob/927586990eb9bc8403a3831247847bdd3bf60423/src/wallet/feebumper.cpp#L176-L187

@notmandatory

Copy link
Copy Markdown
MemberAuthor

There is logic in the existing bdkwallet/mod.rs line 561-570 that will throw an Error::FeeTooLow if the new fee amount is less than the previous fee, but it sounds like there could still be a different issue with this logic, see: bitcoindevkit/bdk_wallet#192

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

Sorry, I am not seeing how the minimum fee issue is relevant here. The issue is reducing external recipient's amount in RBF, which can be a potential bug. Min fee checking will always pass, if someone exploits this (the fee given will then be very high).

bitcoindevkit/bdk_wallet#192 are also fee amount related issues which is orthogonal to this.

@notmandatory

Copy link
Copy Markdown
MemberAuthor

Ok I thought your concern was that bdk isn't enforcing that a bump_fee transaction has a higher fee than the original tx, which I believe is being enforced. With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner. Also keep in mind that allow_shrinking is only allowed for a TxBuilder created with the BumpFee context.

Even so I think it's a valuable feature to be able to bump fee by reducing an external single recipients output for the case where you're sending to a different external wallet that you control.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner.

Yes that is correct. With this attack the attacker won't gain anything, although its a "zero cost micheif" opportunity, which I in my opinion should not be allowed. It's not a critical vulnerability, but an UI/UX gap. There's nothing in the bitcoin protocol itself to stop this from happening. So wallets need to care for it. That's my whole point.

I agree with this current change for fixing the bump_fee operation in bdk-cli, and its also simpler than bitcoindevkit/bdk#42. But I still think bdk should check for this behavior, and should not allow shrinking non wallet addresses. This can be done in a separate PR in bdk and not in bdk-cli, subjected to opinions of others on the same.

This PR is good to go and I think its a good substitution for bitcoindevkit/bdk#42.

@notmandatory

notmandatory commented Nov 1, 2021

Copy link
Copy Markdown
MemberAuthor

Although I see bdk-cli mostly as a test tool that should be able to create any valid bump fee transaction BDK and the bitcoin network will accept, I also see @rajarshimaitra's point that it should demonstrate wallet and BDK best practices.

We can discuss at our team chat tomorrow and if no strong opinions against will merge. :-)
Since bitcoindevkit/bdk#45 is closed I'll go ahead and merge this one.

Replace `wallet bump_fee` command `--send_all` with new
`--shrink ADDRESS` option to reduce the output amount for the
specified address to increase RBF transaction fee.
@notmandatory

Copy link
Copy Markdown
MemberAuthor

Rebased to lastest master.

@notmandatory
notmandatory merged commit b0c78e0 into bitcoindevkit:masterNov 2, 2021
@notmandatorynotmandatory self-assigned this Mar 5, 2022
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants

@notmandatory@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Replace wallet bump_fee command --send_all with new --shrink option - #45

Merged
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall
Nov 2, 2021
Merged

Replace wallet bump_fee command --send_all with new --shrink option#45
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall

Conversation

@notmandatory

@notmandatorynotmandatory commented Oct 7, 2021

Copy link
Copy Markdown
Member

Description

Replace wallet bump_fee command --send_all with new --shrink ADDRESS option to reduce the output amount for the specified address to increase RBF transaction fee.

Notes to the reviewers

This new option is primarily needed when bumping the fee of a send_all transaction or any other transaction that doesn't have a change output that can be reduced to bump the fee on the new RBF transaction.

Steps I used to test

  1. create wallet with two utxos
  2. create and broadcast send_all tx with rbf enabled and 1 sat/vbyte fee back to testnet faucet
  3. create and broadcast bump_fee rbf for above tx with 7 sat/vbyte fee and shrinking the testnet faucet address

https://mempool.space/testnet/tx/e35892843875e084f39c5285ee6f522764210351f78cd89305a49efbf4bfea48

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@notmandatorynotmandatory mentioned this pull request Oct 8, 2021
3 tasks

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah right. We could get the scriptpubkey from specifying the address. And it seems bdk internal doesn't care if the address belongs to us or not, while shrinking.

But I am thinking, doesn't this opens an attack vector in bdk wallet code?

For example I can construct a transaction to a merchant, with very low fee. He will see money coming into his wallet (as many doesn't wait for confirmations). Then half an hour later after leaving the shop, I can then bumpfee to reduce the merchant's output to 0.

The cost of this attack is basically zero, because the attacker will not loose any more money, than he already paid for. He has already spent his input and will get the change back.

Note: This behavior of not to decrease external recipient's amount is not enforced by the bitcoin protocol (it can't be). It is an wallet level feature. And I think wallets implementing bumpfee will need to account for that in their impls.

For reference, heres the doc for bumpfee behaviour of the Bitcoin Core wallet. It doesn't allow reducing external outputs, and if there isn't any change ouput in a tx, the wallet will proactively add one.

https://developer.bitcoin.org/reference/rpc/bumpfee.html

This where the change selection logic happens in bitcoin core wallet.
https://github.com/bitcoin/bitcoin/blob/927586990eb9bc8403a3831247847bdd3bf60423/src/wallet/feebumper.cpp#L176-L187

@notmandatory

Copy link
Copy Markdown
MemberAuthor

There is logic in the existing bdkwallet/mod.rs line 561-570 that will throw an Error::FeeTooLow if the new fee amount is less than the previous fee, but it sounds like there could still be a different issue with this logic, see: bitcoindevkit/bdk_wallet#192

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

Sorry, I am not seeing how the minimum fee issue is relevant here. The issue is reducing external recipient's amount in RBF, which can be a potential bug. Min fee checking will always pass, if someone exploits this (the fee given will then be very high).

bitcoindevkit/bdk_wallet#192 are also fee amount related issues which is orthogonal to this.

@notmandatory

Copy link
Copy Markdown
MemberAuthor

Ok I thought your concern was that bdk isn't enforcing that a bump_fee transaction has a higher fee than the original tx, which I believe is being enforced. With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner. Also keep in mind that allow_shrinking is only allowed for a TxBuilder created with the BumpFee context.

Even so I think it's a valuable feature to be able to bump fee by reducing an external single recipients output for the case where you're sending to a different external wallet that you control.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner.

Yes that is correct. With this attack the attacker won't gain anything, although its a "zero cost micheif" opportunity, which I in my opinion should not be allowed. It's not a critical vulnerability, but an UI/UX gap. There's nothing in the bitcoin protocol itself to stop this from happening. So wallets need to care for it. That's my whole point.

I agree with this current change for fixing the bump_fee operation in bdk-cli, and its also simpler than bitcoindevkit/bdk#42. But I still think bdk should check for this behavior, and should not allow shrinking non wallet addresses. This can be done in a separate PR in bdk and not in bdk-cli, subjected to opinions of others on the same.

This PR is good to go and I think its a good substitution for bitcoindevkit/bdk#42.

@notmandatory

notmandatory commented Nov 1, 2021

Copy link
Copy Markdown
MemberAuthor

Although I see bdk-cli mostly as a test tool that should be able to create any valid bump fee transaction BDK and the bitcoin network will accept, I also see @rajarshimaitra's point that it should demonstrate wallet and BDK best practices.

We can discuss at our team chat tomorrow and if no strong opinions against will merge. :-)
Since bitcoindevkit/bdk#45 is closed I'll go ahead and merge this one.

Replace `wallet bump_fee` command `--send_all` with new
`--shrink ADDRESS` option to reduce the output amount for the
specified address to increase RBF transaction fee.
@notmandatory

Copy link
Copy Markdown
MemberAuthor

Rebased to lastest master.

@notmandatory
notmandatory merged commit b0c78e0 into bitcoindevkit:masterNov 2, 2021
@notmandatorynotmandatory self-assigned this Mar 5, 2022
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants

@notmandatory@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Replace wallet bump_fee command --send_all with new --shrink option - #45

Merged
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall
Nov 2, 2021
Merged

Replace wallet bump_fee command --send_all with new --shrink option#45
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall

Conversation

@notmandatory

@notmandatorynotmandatory commented Oct 7, 2021

Copy link
Copy Markdown
Member

Description

Replace wallet bump_fee command --send_all with new --shrink ADDRESS option to reduce the output amount for the specified address to increase RBF transaction fee.

Notes to the reviewers

This new option is primarily needed when bumping the fee of a send_all transaction or any other transaction that doesn't have a change output that can be reduced to bump the fee on the new RBF transaction.

Steps I used to test

  1. create wallet with two utxos
  2. create and broadcast send_all tx with rbf enabled and 1 sat/vbyte fee back to testnet faucet
  3. create and broadcast bump_fee rbf for above tx with 7 sat/vbyte fee and shrinking the testnet faucet address

https://mempool.space/testnet/tx/e35892843875e084f39c5285ee6f522764210351f78cd89305a49efbf4bfea48

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@notmandatorynotmandatory mentioned this pull request Oct 8, 2021
3 tasks

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah right. We could get the scriptpubkey from specifying the address. And it seems bdk internal doesn't care if the address belongs to us or not, while shrinking.

But I am thinking, doesn't this opens an attack vector in bdk wallet code?

For example I can construct a transaction to a merchant, with very low fee. He will see money coming into his wallet (as many doesn't wait for confirmations). Then half an hour later after leaving the shop, I can then bumpfee to reduce the merchant's output to 0.

The cost of this attack is basically zero, because the attacker will not loose any more money, than he already paid for. He has already spent his input and will get the change back.

Note: This behavior of not to decrease external recipient's amount is not enforced by the bitcoin protocol (it can't be). It is an wallet level feature. And I think wallets implementing bumpfee will need to account for that in their impls.

For reference, heres the doc for bumpfee behaviour of the Bitcoin Core wallet. It doesn't allow reducing external outputs, and if there isn't any change ouput in a tx, the wallet will proactively add one.

https://developer.bitcoin.org/reference/rpc/bumpfee.html

This where the change selection logic happens in bitcoin core wallet.
https://github.com/bitcoin/bitcoin/blob/927586990eb9bc8403a3831247847bdd3bf60423/src/wallet/feebumper.cpp#L176-L187

@notmandatory

Copy link
Copy Markdown
MemberAuthor

There is logic in the existing bdkwallet/mod.rs line 561-570 that will throw an Error::FeeTooLow if the new fee amount is less than the previous fee, but it sounds like there could still be a different issue with this logic, see: bitcoindevkit/bdk_wallet#192

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

Sorry, I am not seeing how the minimum fee issue is relevant here. The issue is reducing external recipient's amount in RBF, which can be a potential bug. Min fee checking will always pass, if someone exploits this (the fee given will then be very high).

bitcoindevkit/bdk_wallet#192 are also fee amount related issues which is orthogonal to this.

@notmandatory

Copy link
Copy Markdown
MemberAuthor

Ok I thought your concern was that bdk isn't enforcing that a bump_fee transaction has a higher fee than the original tx, which I believe is being enforced. With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner. Also keep in mind that allow_shrinking is only allowed for a TxBuilder created with the BumpFee context.

Even so I think it's a valuable feature to be able to bump fee by reducing an external single recipients output for the case where you're sending to a different external wallet that you control.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner.

Yes that is correct. With this attack the attacker won't gain anything, although its a "zero cost micheif" opportunity, which I in my opinion should not be allowed. It's not a critical vulnerability, but an UI/UX gap. There's nothing in the bitcoin protocol itself to stop this from happening. So wallets need to care for it. That's my whole point.

I agree with this current change for fixing the bump_fee operation in bdk-cli, and its also simpler than bitcoindevkit/bdk#42. But I still think bdk should check for this behavior, and should not allow shrinking non wallet addresses. This can be done in a separate PR in bdk and not in bdk-cli, subjected to opinions of others on the same.

This PR is good to go and I think its a good substitution for bitcoindevkit/bdk#42.

@notmandatory

notmandatory commented Nov 1, 2021

Copy link
Copy Markdown
MemberAuthor

Although I see bdk-cli mostly as a test tool that should be able to create any valid bump fee transaction BDK and the bitcoin network will accept, I also see @rajarshimaitra's point that it should demonstrate wallet and BDK best practices.

We can discuss at our team chat tomorrow and if no strong opinions against will merge. :-)
Since bitcoindevkit/bdk#45 is closed I'll go ahead and merge this one.

Replace `wallet bump_fee` command `--send_all` with new
`--shrink ADDRESS` option to reduce the output amount for the
specified address to increase RBF transaction fee.
@notmandatory

Copy link
Copy Markdown
MemberAuthor

Rebased to lastest master.

@notmandatory
notmandatory merged commit b0c78e0 into bitcoindevkit:masterNov 2, 2021
@notmandatorynotmandatory self-assigned this Mar 5, 2022
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants

@notmandatory@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Replace wallet bump_fee command --send_all with new --shrink option - #45

Merged
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall
Nov 2, 2021
Merged

Replace wallet bump_fee command --send_all with new --shrink option#45
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall

Conversation

@notmandatory

@notmandatorynotmandatory commented Oct 7, 2021

Copy link
Copy Markdown
Member

Description

Replace wallet bump_fee command --send_all with new --shrink ADDRESS option to reduce the output amount for the specified address to increase RBF transaction fee.

Notes to the reviewers

This new option is primarily needed when bumping the fee of a send_all transaction or any other transaction that doesn't have a change output that can be reduced to bump the fee on the new RBF transaction.

Steps I used to test

  1. create wallet with two utxos
  2. create and broadcast send_all tx with rbf enabled and 1 sat/vbyte fee back to testnet faucet
  3. create and broadcast bump_fee rbf for above tx with 7 sat/vbyte fee and shrinking the testnet faucet address

https://mempool.space/testnet/tx/e35892843875e084f39c5285ee6f522764210351f78cd89305a49efbf4bfea48

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@notmandatorynotmandatory mentioned this pull request Oct 8, 2021
3 tasks

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah right. We could get the scriptpubkey from specifying the address. And it seems bdk internal doesn't care if the address belongs to us or not, while shrinking.

But I am thinking, doesn't this opens an attack vector in bdk wallet code?

For example I can construct a transaction to a merchant, with very low fee. He will see money coming into his wallet (as many doesn't wait for confirmations). Then half an hour later after leaving the shop, I can then bumpfee to reduce the merchant's output to 0.

The cost of this attack is basically zero, because the attacker will not loose any more money, than he already paid for. He has already spent his input and will get the change back.

Note: This behavior of not to decrease external recipient's amount is not enforced by the bitcoin protocol (it can't be). It is an wallet level feature. And I think wallets implementing bumpfee will need to account for that in their impls.

For reference, heres the doc for bumpfee behaviour of the Bitcoin Core wallet. It doesn't allow reducing external outputs, and if there isn't any change ouput in a tx, the wallet will proactively add one.

https://developer.bitcoin.org/reference/rpc/bumpfee.html

This where the change selection logic happens in bitcoin core wallet.
https://github.com/bitcoin/bitcoin/blob/927586990eb9bc8403a3831247847bdd3bf60423/src/wallet/feebumper.cpp#L176-L187

@notmandatory

Copy link
Copy Markdown
MemberAuthor

There is logic in the existing bdkwallet/mod.rs line 561-570 that will throw an Error::FeeTooLow if the new fee amount is less than the previous fee, but it sounds like there could still be a different issue with this logic, see: bitcoindevkit/bdk_wallet#192

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

Sorry, I am not seeing how the minimum fee issue is relevant here. The issue is reducing external recipient's amount in RBF, which can be a potential bug. Min fee checking will always pass, if someone exploits this (the fee given will then be very high).

bitcoindevkit/bdk_wallet#192 are also fee amount related issues which is orthogonal to this.

@notmandatory

Copy link
Copy Markdown
MemberAuthor

Ok I thought your concern was that bdk isn't enforcing that a bump_fee transaction has a higher fee than the original tx, which I believe is being enforced. With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner. Also keep in mind that allow_shrinking is only allowed for a TxBuilder created with the BumpFee context.

Even so I think it's a valuable feature to be able to bump fee by reducing an external single recipients output for the case where you're sending to a different external wallet that you control.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner.

Yes that is correct. With this attack the attacker won't gain anything, although its a "zero cost micheif" opportunity, which I in my opinion should not be allowed. It's not a critical vulnerability, but an UI/UX gap. There's nothing in the bitcoin protocol itself to stop this from happening. So wallets need to care for it. That's my whole point.

I agree with this current change for fixing the bump_fee operation in bdk-cli, and its also simpler than bitcoindevkit/bdk#42. But I still think bdk should check for this behavior, and should not allow shrinking non wallet addresses. This can be done in a separate PR in bdk and not in bdk-cli, subjected to opinions of others on the same.

This PR is good to go and I think its a good substitution for bitcoindevkit/bdk#42.

@notmandatory

notmandatory commented Nov 1, 2021

Copy link
Copy Markdown
MemberAuthor

Although I see bdk-cli mostly as a test tool that should be able to create any valid bump fee transaction BDK and the bitcoin network will accept, I also see @rajarshimaitra's point that it should demonstrate wallet and BDK best practices.

We can discuss at our team chat tomorrow and if no strong opinions against will merge. :-)
Since bitcoindevkit/bdk#45 is closed I'll go ahead and merge this one.

Replace `wallet bump_fee` command `--send_all` with new
`--shrink ADDRESS` option to reduce the output amount for the
specified address to increase RBF transaction fee.
@notmandatory

Copy link
Copy Markdown
MemberAuthor

Rebased to lastest master.

@notmandatory
notmandatory merged commit b0c78e0 into bitcoindevkit:masterNov 2, 2021
@notmandatorynotmandatory self-assigned this Mar 5, 2022
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants

@notmandatory@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Replace wallet bump_fee command --send_all with new --shrink option - #45

Merged
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall
Nov 2, 2021
Merged

Replace wallet bump_fee command --send_all with new --shrink option#45
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall

Conversation

@notmandatory

@notmandatorynotmandatory commented Oct 7, 2021

Copy link
Copy Markdown
Member

Description

Replace wallet bump_fee command --send_all with new --shrink ADDRESS option to reduce the output amount for the specified address to increase RBF transaction fee.

Notes to the reviewers

This new option is primarily needed when bumping the fee of a send_all transaction or any other transaction that doesn't have a change output that can be reduced to bump the fee on the new RBF transaction.

Steps I used to test

  1. create wallet with two utxos
  2. create and broadcast send_all tx with rbf enabled and 1 sat/vbyte fee back to testnet faucet
  3. create and broadcast bump_fee rbf for above tx with 7 sat/vbyte fee and shrinking the testnet faucet address

https://mempool.space/testnet/tx/e35892843875e084f39c5285ee6f522764210351f78cd89305a49efbf4bfea48

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@notmandatorynotmandatory mentioned this pull request Oct 8, 2021
3 tasks

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah right. We could get the scriptpubkey from specifying the address. And it seems bdk internal doesn't care if the address belongs to us or not, while shrinking.

But I am thinking, doesn't this opens an attack vector in bdk wallet code?

For example I can construct a transaction to a merchant, with very low fee. He will see money coming into his wallet (as many doesn't wait for confirmations). Then half an hour later after leaving the shop, I can then bumpfee to reduce the merchant's output to 0.

The cost of this attack is basically zero, because the attacker will not loose any more money, than he already paid for. He has already spent his input and will get the change back.

Note: This behavior of not to decrease external recipient's amount is not enforced by the bitcoin protocol (it can't be). It is an wallet level feature. And I think wallets implementing bumpfee will need to account for that in their impls.

For reference, heres the doc for bumpfee behaviour of the Bitcoin Core wallet. It doesn't allow reducing external outputs, and if there isn't any change ouput in a tx, the wallet will proactively add one.

https://developer.bitcoin.org/reference/rpc/bumpfee.html

This where the change selection logic happens in bitcoin core wallet.
https://github.com/bitcoin/bitcoin/blob/927586990eb9bc8403a3831247847bdd3bf60423/src/wallet/feebumper.cpp#L176-L187

@notmandatory

Copy link
Copy Markdown
MemberAuthor

There is logic in the existing bdkwallet/mod.rs line 561-570 that will throw an Error::FeeTooLow if the new fee amount is less than the previous fee, but it sounds like there could still be a different issue with this logic, see: bitcoindevkit/bdk_wallet#192

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

Sorry, I am not seeing how the minimum fee issue is relevant here. The issue is reducing external recipient's amount in RBF, which can be a potential bug. Min fee checking will always pass, if someone exploits this (the fee given will then be very high).

bitcoindevkit/bdk_wallet#192 are also fee amount related issues which is orthogonal to this.

@notmandatory

Copy link
Copy Markdown
MemberAuthor

Ok I thought your concern was that bdk isn't enforcing that a bump_fee transaction has a higher fee than the original tx, which I believe is being enforced. With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner. Also keep in mind that allow_shrinking is only allowed for a TxBuilder created with the BumpFee context.

Even so I think it's a valuable feature to be able to bump fee by reducing an external single recipients output for the case where you're sending to a different external wallet that you control.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner.

Yes that is correct. With this attack the attacker won't gain anything, although its a "zero cost micheif" opportunity, which I in my opinion should not be allowed. It's not a critical vulnerability, but an UI/UX gap. There's nothing in the bitcoin protocol itself to stop this from happening. So wallets need to care for it. That's my whole point.

I agree with this current change for fixing the bump_fee operation in bdk-cli, and its also simpler than bitcoindevkit/bdk#42. But I still think bdk should check for this behavior, and should not allow shrinking non wallet addresses. This can be done in a separate PR in bdk and not in bdk-cli, subjected to opinions of others on the same.

This PR is good to go and I think its a good substitution for bitcoindevkit/bdk#42.

@notmandatory

notmandatory commented Nov 1, 2021

Copy link
Copy Markdown
MemberAuthor

Although I see bdk-cli mostly as a test tool that should be able to create any valid bump fee transaction BDK and the bitcoin network will accept, I also see @rajarshimaitra's point that it should demonstrate wallet and BDK best practices.

We can discuss at our team chat tomorrow and if no strong opinions against will merge. :-)
Since bitcoindevkit/bdk#45 is closed I'll go ahead and merge this one.

Replace `wallet bump_fee` command `--send_all` with new
`--shrink ADDRESS` option to reduce the output amount for the
specified address to increase RBF transaction fee.
@notmandatory

Copy link
Copy Markdown
MemberAuthor

Rebased to lastest master.

@notmandatory
notmandatory merged commit b0c78e0 into bitcoindevkit:masterNov 2, 2021
@notmandatorynotmandatory self-assigned this Mar 5, 2022
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants

@notmandatory@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Replace wallet bump_fee command --send_all with new --shrink option - #45

Merged
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall
Nov 2, 2021
Merged

Replace wallet bump_fee command --send_all with new --shrink option#45
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall

Conversation

@notmandatory

@notmandatorynotmandatory commented Oct 7, 2021

Copy link
Copy Markdown
Member

Description

Replace wallet bump_fee command --send_all with new --shrink ADDRESS option to reduce the output amount for the specified address to increase RBF transaction fee.

Notes to the reviewers

This new option is primarily needed when bumping the fee of a send_all transaction or any other transaction that doesn't have a change output that can be reduced to bump the fee on the new RBF transaction.

Steps I used to test

  1. create wallet with two utxos
  2. create and broadcast send_all tx with rbf enabled and 1 sat/vbyte fee back to testnet faucet
  3. create and broadcast bump_fee rbf for above tx with 7 sat/vbyte fee and shrinking the testnet faucet address

https://mempool.space/testnet/tx/e35892843875e084f39c5285ee6f522764210351f78cd89305a49efbf4bfea48

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@notmandatorynotmandatory mentioned this pull request Oct 8, 2021
3 tasks

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah right. We could get the scriptpubkey from specifying the address. And it seems bdk internal doesn't care if the address belongs to us or not, while shrinking.

But I am thinking, doesn't this opens an attack vector in bdk wallet code?

For example I can construct a transaction to a merchant, with very low fee. He will see money coming into his wallet (as many doesn't wait for confirmations). Then half an hour later after leaving the shop, I can then bumpfee to reduce the merchant's output to 0.

The cost of this attack is basically zero, because the attacker will not loose any more money, than he already paid for. He has already spent his input and will get the change back.

Note: This behavior of not to decrease external recipient's amount is not enforced by the bitcoin protocol (it can't be). It is an wallet level feature. And I think wallets implementing bumpfee will need to account for that in their impls.

For reference, heres the doc for bumpfee behaviour of the Bitcoin Core wallet. It doesn't allow reducing external outputs, and if there isn't any change ouput in a tx, the wallet will proactively add one.

https://developer.bitcoin.org/reference/rpc/bumpfee.html

This where the change selection logic happens in bitcoin core wallet.
https://github.com/bitcoin/bitcoin/blob/927586990eb9bc8403a3831247847bdd3bf60423/src/wallet/feebumper.cpp#L176-L187

@notmandatory

Copy link
Copy Markdown
MemberAuthor

There is logic in the existing bdkwallet/mod.rs line 561-570 that will throw an Error::FeeTooLow if the new fee amount is less than the previous fee, but it sounds like there could still be a different issue with this logic, see: bitcoindevkit/bdk_wallet#192

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

Sorry, I am not seeing how the minimum fee issue is relevant here. The issue is reducing external recipient's amount in RBF, which can be a potential bug. Min fee checking will always pass, if someone exploits this (the fee given will then be very high).

bitcoindevkit/bdk_wallet#192 are also fee amount related issues which is orthogonal to this.

@notmandatory

Copy link
Copy Markdown
MemberAuthor

Ok I thought your concern was that bdk isn't enforcing that a bump_fee transaction has a higher fee than the original tx, which I believe is being enforced. With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner. Also keep in mind that allow_shrinking is only allowed for a TxBuilder created with the BumpFee context.

Even so I think it's a valuable feature to be able to bump fee by reducing an external single recipients output for the case where you're sending to a different external wallet that you control.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner.

Yes that is correct. With this attack the attacker won't gain anything, although its a "zero cost micheif" opportunity, which I in my opinion should not be allowed. It's not a critical vulnerability, but an UI/UX gap. There's nothing in the bitcoin protocol itself to stop this from happening. So wallets need to care for it. That's my whole point.

I agree with this current change for fixing the bump_fee operation in bdk-cli, and its also simpler than bitcoindevkit/bdk#42. But I still think bdk should check for this behavior, and should not allow shrinking non wallet addresses. This can be done in a separate PR in bdk and not in bdk-cli, subjected to opinions of others on the same.

This PR is good to go and I think its a good substitution for bitcoindevkit/bdk#42.

@notmandatory

notmandatory commented Nov 1, 2021

Copy link
Copy Markdown
MemberAuthor

Although I see bdk-cli mostly as a test tool that should be able to create any valid bump fee transaction BDK and the bitcoin network will accept, I also see @rajarshimaitra's point that it should demonstrate wallet and BDK best practices.

We can discuss at our team chat tomorrow and if no strong opinions against will merge. :-)
Since bitcoindevkit/bdk#45 is closed I'll go ahead and merge this one.

Replace `wallet bump_fee` command `--send_all` with new
`--shrink ADDRESS` option to reduce the output amount for the
specified address to increase RBF transaction fee.
@notmandatory

Copy link
Copy Markdown
MemberAuthor

Rebased to lastest master.

@notmandatory
notmandatory merged commit b0c78e0 into bitcoindevkit:masterNov 2, 2021
@notmandatorynotmandatory self-assigned this Mar 5, 2022
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants

@notmandatory@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Replace wallet bump_fee command --send_all with new --shrink option - #45

Merged
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall
Nov 2, 2021
Merged

Replace wallet bump_fee command --send_all with new --shrink option#45
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall

Conversation

@notmandatory

@notmandatorynotmandatory commented Oct 7, 2021

Copy link
Copy Markdown
Member

Description

Replace wallet bump_fee command --send_all with new --shrink ADDRESS option to reduce the output amount for the specified address to increase RBF transaction fee.

Notes to the reviewers

This new option is primarily needed when bumping the fee of a send_all transaction or any other transaction that doesn't have a change output that can be reduced to bump the fee on the new RBF transaction.

Steps I used to test

  1. create wallet with two utxos
  2. create and broadcast send_all tx with rbf enabled and 1 sat/vbyte fee back to testnet faucet
  3. create and broadcast bump_fee rbf for above tx with 7 sat/vbyte fee and shrinking the testnet faucet address

https://mempool.space/testnet/tx/e35892843875e084f39c5285ee6f522764210351f78cd89305a49efbf4bfea48

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@notmandatorynotmandatory mentioned this pull request Oct 8, 2021
3 tasks

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah right. We could get the scriptpubkey from specifying the address. And it seems bdk internal doesn't care if the address belongs to us or not, while shrinking.

But I am thinking, doesn't this opens an attack vector in bdk wallet code?

For example I can construct a transaction to a merchant, with very low fee. He will see money coming into his wallet (as many doesn't wait for confirmations). Then half an hour later after leaving the shop, I can then bumpfee to reduce the merchant's output to 0.

The cost of this attack is basically zero, because the attacker will not loose any more money, than he already paid for. He has already spent his input and will get the change back.

Note: This behavior of not to decrease external recipient's amount is not enforced by the bitcoin protocol (it can't be). It is an wallet level feature. And I think wallets implementing bumpfee will need to account for that in their impls.

For reference, heres the doc for bumpfee behaviour of the Bitcoin Core wallet. It doesn't allow reducing external outputs, and if there isn't any change ouput in a tx, the wallet will proactively add one.

https://developer.bitcoin.org/reference/rpc/bumpfee.html

This where the change selection logic happens in bitcoin core wallet.
https://github.com/bitcoin/bitcoin/blob/927586990eb9bc8403a3831247847bdd3bf60423/src/wallet/feebumper.cpp#L176-L187

@notmandatory

Copy link
Copy Markdown
MemberAuthor

There is logic in the existing bdkwallet/mod.rs line 561-570 that will throw an Error::FeeTooLow if the new fee amount is less than the previous fee, but it sounds like there could still be a different issue with this logic, see: bitcoindevkit/bdk_wallet#192

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

Sorry, I am not seeing how the minimum fee issue is relevant here. The issue is reducing external recipient's amount in RBF, which can be a potential bug. Min fee checking will always pass, if someone exploits this (the fee given will then be very high).

bitcoindevkit/bdk_wallet#192 are also fee amount related issues which is orthogonal to this.

@notmandatory

Copy link
Copy Markdown
MemberAuthor

Ok I thought your concern was that bdk isn't enforcing that a bump_fee transaction has a higher fee than the original tx, which I believe is being enforced. With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner. Also keep in mind that allow_shrinking is only allowed for a TxBuilder created with the BumpFee context.

Even so I think it's a valuable feature to be able to bump fee by reducing an external single recipients output for the case where you're sending to a different external wallet that you control.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner.

Yes that is correct. With this attack the attacker won't gain anything, although its a "zero cost micheif" opportunity, which I in my opinion should not be allowed. It's not a critical vulnerability, but an UI/UX gap. There's nothing in the bitcoin protocol itself to stop this from happening. So wallets need to care for it. That's my whole point.

I agree with this current change for fixing the bump_fee operation in bdk-cli, and its also simpler than bitcoindevkit/bdk#42. But I still think bdk should check for this behavior, and should not allow shrinking non wallet addresses. This can be done in a separate PR in bdk and not in bdk-cli, subjected to opinions of others on the same.

This PR is good to go and I think its a good substitution for bitcoindevkit/bdk#42.

@notmandatory

notmandatory commented Nov 1, 2021

Copy link
Copy Markdown
MemberAuthor

Although I see bdk-cli mostly as a test tool that should be able to create any valid bump fee transaction BDK and the bitcoin network will accept, I also see @rajarshimaitra's point that it should demonstrate wallet and BDK best practices.

We can discuss at our team chat tomorrow and if no strong opinions against will merge. :-)
Since bitcoindevkit/bdk#45 is closed I'll go ahead and merge this one.

Replace `wallet bump_fee` command `--send_all` with new
`--shrink ADDRESS` option to reduce the output amount for the
specified address to increase RBF transaction fee.
@notmandatory

Copy link
Copy Markdown
MemberAuthor

Rebased to lastest master.

@notmandatory
notmandatory merged commit b0c78e0 into bitcoindevkit:masterNov 2, 2021
@notmandatorynotmandatory self-assigned this Mar 5, 2022
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants

@notmandatory@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Replace wallet bump_fee command --send_all with new --shrink option - #45

Merged
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall
Nov 2, 2021
Merged

Replace wallet bump_fee command --send_all with new --shrink option#45
notmandatory merged 1 commit into
bitcoindevkit:masterfrom
notmandatory:bump_sendall

Conversation

@notmandatory

@notmandatorynotmandatory commented Oct 7, 2021

Copy link
Copy Markdown
Member

Description

Replace wallet bump_fee command --send_all with new --shrink ADDRESS option to reduce the output amount for the specified address to increase RBF transaction fee.

Notes to the reviewers

This new option is primarily needed when bumping the fee of a send_all transaction or any other transaction that doesn't have a change output that can be reduced to bump the fee on the new RBF transaction.

Steps I used to test

  1. create wallet with two utxos
  2. create and broadcast send_all tx with rbf enabled and 1 sat/vbyte fee back to testnet faucet
  3. create and broadcast bump_fee rbf for above tx with 7 sat/vbyte fee and shrinking the testnet faucet address

https://mempool.space/testnet/tx/e35892843875e084f39c5285ee6f522764210351f78cd89305a49efbf4bfea48

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature
  • I've updated CHANGELOG.md

@notmandatorynotmandatory mentioned this pull request Oct 8, 2021
3 tasks

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah right. We could get the scriptpubkey from specifying the address. And it seems bdk internal doesn't care if the address belongs to us or not, while shrinking.

But I am thinking, doesn't this opens an attack vector in bdk wallet code?

For example I can construct a transaction to a merchant, with very low fee. He will see money coming into his wallet (as many doesn't wait for confirmations). Then half an hour later after leaving the shop, I can then bumpfee to reduce the merchant's output to 0.

The cost of this attack is basically zero, because the attacker will not loose any more money, than he already paid for. He has already spent his input and will get the change back.

Note: This behavior of not to decrease external recipient's amount is not enforced by the bitcoin protocol (it can't be). It is an wallet level feature. And I think wallets implementing bumpfee will need to account for that in their impls.

For reference, heres the doc for bumpfee behaviour of the Bitcoin Core wallet. It doesn't allow reducing external outputs, and if there isn't any change ouput in a tx, the wallet will proactively add one.

https://developer.bitcoin.org/reference/rpc/bumpfee.html

This where the change selection logic happens in bitcoin core wallet.
https://github.com/bitcoin/bitcoin/blob/927586990eb9bc8403a3831247847bdd3bf60423/src/wallet/feebumper.cpp#L176-L187

@notmandatory

Copy link
Copy Markdown
MemberAuthor

There is logic in the existing bdkwallet/mod.rs line 561-570 that will throw an Error::FeeTooLow if the new fee amount is less than the previous fee, but it sounds like there could still be a different issue with this logic, see: bitcoindevkit/bdk_wallet#192

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

For the purposed of this PR I think it's OK to allow bumping fees to external receivers even if there could be a missing case in the minimum fee logic, at least bdk requires the bump fee be greater than the current tx fee.

Sorry, I am not seeing how the minimum fee issue is relevant here. The issue is reducing external recipient's amount in RBF, which can be a potential bug. Min fee checking will always pass, if someone exploits this (the fee given will then be very high).

bitcoindevkit/bdk_wallet#192 are also fee amount related issues which is orthogonal to this.

@notmandatory

Copy link
Copy Markdown
MemberAuthor

Ok I thought your concern was that bdk isn't enforcing that a bump_fee transaction has a higher fee than the original tx, which I believe is being enforced. With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner. Also keep in mind that allow_shrinking is only allowed for a TxBuilder created with the BumpFee context.

Even so I think it's a valuable feature to be able to bump fee by reducing an external single recipients output for the case where you're sending to a different external wallet that you control.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

With the current bump fee API I don't see how you could reduce the external recipients amount to zero except by setting such a high tx fee that it eats up all the sent amount. In this case the attacker is cheating the external recipient, but isn't gaining much since the output amount now goes to the miner.

Yes that is correct. With this attack the attacker won't gain anything, although its a "zero cost micheif" opportunity, which I in my opinion should not be allowed. It's not a critical vulnerability, but an UI/UX gap. There's nothing in the bitcoin protocol itself to stop this from happening. So wallets need to care for it. That's my whole point.

I agree with this current change for fixing the bump_fee operation in bdk-cli, and its also simpler than bitcoindevkit/bdk#42. But I still think bdk should check for this behavior, and should not allow shrinking non wallet addresses. This can be done in a separate PR in bdk and not in bdk-cli, subjected to opinions of others on the same.

This PR is good to go and I think its a good substitution for bitcoindevkit/bdk#42.

@notmandatory

notmandatory commented Nov 1, 2021

Copy link
Copy Markdown
MemberAuthor

Although I see bdk-cli mostly as a test tool that should be able to create any valid bump fee transaction BDK and the bitcoin network will accept, I also see @rajarshimaitra's point that it should demonstrate wallet and BDK best practices.

We can discuss at our team chat tomorrow and if no strong opinions against will merge. :-)
Since bitcoindevkit/bdk#45 is closed I'll go ahead and merge this one.

Replace `wallet bump_fee` command `--send_all` with new
`--shrink ADDRESS` option to reduce the output amount for the
specified address to increase RBF transaction fee.
@notmandatory

Copy link
Copy Markdown
MemberAuthor

Rebased to lastest master.

@notmandatory
notmandatory merged commit b0c78e0 into bitcoindevkit:masterNov 2, 2021
@notmandatorynotmandatory self-assigned this Mar 5, 2022
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants

@notmandatory@rajarshimaitra