-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Disable default fallbackfee on mainnet #11882
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
Conversation
69f76ba
to
0cc0c25
Compare
Concept ACK on setting the rbf flag on transactions where it is unclear if they confirm with the default fallback fee fee. Not yet sure about adding a command line arg just to disable and disallow fallbackfee. |
Using a static (!) fallback fee seems an incorrect concept. It will very likely result in significant overpay or significant underpay (==stuck transaction). I would even vote for defaulting |
I think |
0cc0c25
to
9aa8a67
Compare
If fee estimates are not available perhaps is best to ask the user to wait or to manually set a fee rate (if they are a sufficiently advanced user, maybe even behind a config flag to reduce mistakes). BIP125 replacement enabled helps only the case when you underpay and does nothing for overpaying. |
Well, instead of adding a command line arg to disable fallbackfee, why not remove the default value for fallbackfee and require that it is set whenever it is used? |
Removing the fallback fee entirely would be an abrupt task and it would probably make regression tests more difficult.
|
I think I am bad at choosing words. Let me explain by example:
|
That would disable the fallback fee by default. Right? |
Jup, if we want to disable by default, I'd prefer that way. |
Agree with @MarcoFalke we already have too many configuration options Sometimes we err too much on maintaining every aspect of backwards compatibility. We also already have the option to include the fee on a per transaction basis . |
How would we handle regression tests (enable fallbackfee by default there)? |
However, I'm fine with skipping step 1) (allow to disable) and directly disable it by default (with allow to enable). |
Thats a good question. |
Jup, that makes sense to me. Don't worry too much about the tests for now, you can ignore the travis result and then later push a test-fix commit that follows your implementation and is acceptable to everyone. |
9aa8a67
to
7f12981
Compare
|
@jonasschnelli Can we please get rid of both of the new options? I haven't understood why they are necessary. We already have
|
7f12981
to
9bb0390
Compare
Followed @morcos advice. |
9bb0390
to
7941d0e
Compare
@jonasschnelli Needs rebase if still relevant. Also see #11918 |
7941d0e
to
edcc468
Compare
self.start_node(0, extra_args=["-fallbackfee=0"]) | ||
addr = self.nodes[0].getnewaddress() | ||
assert_raises_rpc_error(-4, "Fee estimation failed", self.nodes[0].sendtoaddress, addr, 1) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could also add tests for the other rpc that potentially hit this error:
E.g.
assert_raises_rpc_error(-4, "Fee estimation failed. Fallbackfee is disabled", lambda: self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1})))
assert_raises_rpc_error(-4, "Fee estimation failed. Fallbackfee is disabled", lambda: self.nodes[0].sendfrom("", self.nodes[0].getnewaddress(), 1))
assert_raises_rpc_error(-6, "Fee estimation failed. Fallbackfee is disabled", lambda: self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1}))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks.
Added those tests.
8ba3ffb
to
93ba98a
Compare
Thanks for adding the tests. I also slightly tested a previous version in the gui.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs rebase.
Concept ACK on setting the rbf flag on transactions where it is unclear if they confirm with the default fallback fee
I see 2 distinct options here: 1) automatically set RBF; 2) give error if coin control RBF is not set. From the UI point of view, being "preventive" is not that bad, I would go for option 2).
I think we can just warn people using RPC that if they set a fallbackfee and don't have rbf set, then they are taking some risk
Should update descriptions of send/fund RPC?
|
||
# test sending a tx with disabled fallback fee (must fail) | ||
self.stop_nodes() | ||
self.start_node(0, extra_args=["-fallbackfee=0"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove stop
above and change here to restart
.
93ba98a
to
a357763
Compare
Rebased and fixed the test nit reported by @promag.
The idea 1) has been removed (was there in a previous version of Core): #11882 (comment) |
Should probably use underscore for the test name (see other test script names) |
a357763
to
0d51422
Compare
Fixed the test name (uses now underscore). |
src/wallet/init.cpp
Outdated
@@ -15,6 +16,9 @@ | |||
|
|||
std::string GetWalletHelpString(bool showDebug) | |||
{ | |||
const auto defaultChainParams = CreateChainParams(CBaseChainParams::MAIN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused, remove? same below.
src/wallet/init.cpp
Outdated
@@ -132,6 +139,7 @@ bool WalletParameterInteraction() | |||
InitWarning(AmountHighWarn("-fallbackfee") + " " + | |||
_("This is the transaction fee you may pay when fee estimates are not available.")); | |||
CWallet::fallbackFee = CFeeRate(nFeePerK); | |||
g_wallet_allow_fallback_fee = (nFeePerK == 0 ? false : true); //disable fallback fee in case value was set to 0, enable if non-null value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit
g_wallet_allow_fallback_fee = nFeePerK != 0;
assert_raises_rpc_error(-4, "Fee estimation failed", lambda: self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))) | ||
assert_raises_rpc_error(-4, "Fee estimation failed", lambda: self.nodes[0].sendfrom("", self.nodes[0].getnewaddress(), 1)) | ||
assert_raises_rpc_error(-6, "Fee estimation failed", lambda: self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1})) | ||
if __name__ == '__main__': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing newline before.
@@ -91,6 +93,7 @@ class CChainParams | |||
bool fMineBlocksOnDemand; | |||
CCheckpointData checkpointData; | |||
ChainTxData chainTxData; | |||
bool m_fallback_fee_enabled; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit, could be after fMineBlocksOnDemand
above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take the following example:
#include <iostream>
using namespace std;
struct s1 {
char a;
int b;
};
struct s2 {
char a;
int b;
char c;
};
struct s3 {
char a;
char c;
int b;
};
int main() {
cout << sizeof(s1) << endl;
cout << sizeof(s2) << endl;
cout << sizeof(s3) << endl;
return 0;
}
on my system the output is
8
12
8
See http://www.catb.org/esr/structure-packing/#_structure_alignment_and_padding
But it's no big deal in this case, but should be taken into account when it's instanced a lot.
src/wallet/init.cpp
Outdated
@@ -123,6 +127,9 @@ bool WalletParameterInteraction() | |||
_("This is the minimum transaction fee you pay on every transaction.")); | |||
CWallet::minTxFee = CFeeRate(n); | |||
} | |||
|
|||
const CChainParams& chainParams = Params(); | |||
g_wallet_allow_fallback_fee = chainParams.IsFallbackFeeEnabled(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit, shorter:
g_wallet_allow_fallback_fee = Params().IsFallbackFeeEnabled();
@@ -44,6 +44,7 @@ bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; | |||
bool fWalletRbf = DEFAULT_WALLET_RBF; | |||
OutputType g_address_type = OUTPUT_TYPE_NONE; | |||
OutputType g_change_type = OUTPUT_TYPE_NONE; | |||
bool g_wallet_allow_fallback_fee = false; //<! will be defined via chainparams |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following the same concept of #12408, move to wallet member?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fallback fee yes or now seems to me after a global setting (not per wallet).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In which case it could be a static member, just saying
0d51422
to
3e02133
Compare
3e02133
to
2876598
Compare
Fixed points reported by @promag |
2876598
to
3f592b8
Compare
Only changes were feedback addressed by promag.
|
utACK 3f592b8. |
3f592b8 [QA] add wallet-rbf test (Jonas Schnelli) 8222e05 Disable wallet fallbackfee by default on mainnet (Jonas Schnelli) Pull request description: Removes the default fallback fee on mainnet (but keeps it on testnet/regtest). Transactions using the fallbackfee in case the fallback fee has not been set are getting rejected. Tree-SHA512: e54d2594b7f954e640cc513a18b0bfbe189f15e15bdeed4fe02b7677f939bca1731fef781b073127ffd4ce08a595fb118259b8826cdaa077ff7d5ae9495810db
New global variables were introduced in bitcoin#11882 and not setting them causes: wallet/test/wallet_tests.cpp(638): error in "ListCoins": check wallet->CreateTransaction({recipient}, wtx, reservekey, fee, changePos, error, dummy) failed wallet/test/wallet_tests.cpp(679): error in "ListCoins": check list.begin()->second.size() == 2 failed [1 != 2] wallet/test/wallet_tests.cpp(686): error in "ListCoins": check available.size() == 2 failed [1 != 2] wallet/test/wallet_tests.cpp(705): error in "ListCoins": check list.begin()->second.size() == 2 failed [1 != 2] It's possible to reproduce the failure reliably by running: src/test/test_bitcoin --log_level=test_suite --run_test=wallet_tests/ListCoins Failures happen nondeterministically because boost test framework doesn't run tests in a specified order, and tests that run previously can set the global variables and mask the bug.
…fallback_fee 7ba2d57 Fix ListCoins test failure due to unset g_wallet_allow_fallback_fee (Russell Yanofsky) Pull request description: New global variable was introduced in #11882 and not setting it causes: ``` wallet/test/wallet_tests.cpp(638): error in "ListCoins": check wallet->CreateTransaction({recipient}, wtx, reservekey, fee, changePos, error, dummy) failed wallet/test/wallet_tests.cpp(679): error in "ListCoins": check list.begin()->second.size() == 2 failed [1 != 2] wallet/test/wallet_tests.cpp(686): error in "ListCoins": check available.size() == 2 failed [1 != 2] wallet/test/wallet_tests.cpp(705): error in "ListCoins": check list.begin()->second.size() == 2 failed [1 != 2] ``` It's possible to reproduce the failure reliably by running: ``` src/test/test_bitcoin --log_level=test_suite --run_test=wallet_tests/ListCoins ``` Failures happen nondeterministically because boost test framework doesn't run tests in a specified order, and tests that run previously can set the global variables and mask the bug. This is similar to bugs #12150 and #12424. Example travis failures are: https://travis-ci.org/bitcoin/bitcoin/jobs/348296805#L2676 https://travis-ci.org/bitcoin/bitcoin/jobs/348362560#L2769 https://travis-ci.org/bitcoin/bitcoin/jobs/348362563#L2824 Tree-SHA512: ca37b554a75c12ac2d534de62bf74eb9e0b29e4399ebf1fa10053a40887e55e9e7135f754a01e5a67499cc8677ae226542146b370b1e83d08bb63d79ff379073
New global variables were introduced in bitcoin#11882 and not setting them causes: wallet/test/wallet_tests.cpp(638): error in "ListCoins": check wallet->CreateTransaction({recipient}, wtx, reservekey, fee, changePos, error, dummy) failed wallet/test/wallet_tests.cpp(679): error in "ListCoins": check list.begin()->second.size() == 2 failed [1 != 2] wallet/test/wallet_tests.cpp(686): error in "ListCoins": check available.size() == 2 failed [1 != 2] wallet/test/wallet_tests.cpp(705): error in "ListCoins": check list.begin()->second.size() == 2 failed [1 != 2] It's possible to reproduce the failure reliably by running: src/test/test_bitcoin --log_level=test_suite --run_test=wallet_tests/ListCoins Failures happen nondeterministically because boost test framework doesn't run tests in a specified order, and tests that run previously can set the global variables and mask the bug.
New global variables were introduced in bitcoin#11882 and not setting them causes: wallet/test/wallet_tests.cpp(638): error in "ListCoins": check wallet->CreateTransaction({recipient}, wtx, reservekey, fee, changePos, error, dummy) failed wallet/test/wallet_tests.cpp(679): error in "ListCoins": check list.begin()->second.size() == 2 failed [1 != 2] wallet/test/wallet_tests.cpp(686): error in "ListCoins": check available.size() == 2 failed [1 != 2] wallet/test/wallet_tests.cpp(705): error in "ListCoins": check list.begin()->second.size() == 2 failed [1 != 2] It's possible to reproduce the failure reliably by running: src/test/test_bitcoin --log_level=test_suite --run_test=wallet_tests/ListCoins Failures happen nondeterministically because boost test framework doesn't run tests in a specified order, and tests that run previously can set the global variables and mask the bug.
Removes the default fallback fee on mainnet (but keeps it on testnet/regtest).
Transactions using the fallbackfee in case the fallback fee has not been set are getting rejected.