-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
1.14.5 fees #2485
1.14.5 fees #2485
Conversation
@rnicoll The reason dogecoin/qa/rpc-tests/test_framework/util.py Lines 519 to 521 in 4c93783
does not exist in 1.14.5. I think this is because we no longer round up in kB to calculate fees. I would think removing it and counting actual number of bytes would address that test, but not sure since I am not familiar with the rpc-tests. EDIT 1: The offending line is 645 in that rpc test. dogecoin/qa/rpc-tests/fundrawtransaction.py Line 645 in 81d5fa4
EDIT 2: I ran it with |
@@ -509,15 +509,12 @@ def random_transaction(nodes, amount, min_fee, fee_increment, fee_variants): | |||
|
|||
def assert_fee_amount(fee, tx_size, fee_per_kB): | |||
"""Assert the fee was in range""" | |||
target_fee = fee_per_kB / 1000 | |||
target_fee = tx_size * fee_per_kB / 1000 | |||
if fee < target_fee: |
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.
if fee < target_fee:
raise AssertionError("Fee of %s DOGE too low! (Should be %s DOGE)"%(str(fee), str(target_fee)))
# allow the wallet's estimation to be at most 2 bytes off
if fee > (tx_size + 2) * fee_per_kB / 1000:
raise AssertionError("Fee of %s DOGE too high! (Should be %s DOGE)"%(str(fee), str(target_fee)))
if fee < target_fee: | ||
raise AssertionError("Fee of %s BTC too low! (Should be %s BTC)"%(str(fee), str(target_fee))) |
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.
raise AssertionError("Fee of %s DOGE too low! (Should be %s DOGE)"%(str(fee), str(target_fee)))
# allow the wallet's estimation to be at most 2 bytes off
if fee > (tx_size + 2) * fee_per_kB / 1000:
raise AssertionError("Fee of %s DOGE too high! (Should be %s DOGE)"%(str(fee), str(target_fee)))
@ReverseControl Thanks, fixed up fundrawtransaction.py now |
@chalermchai29 I'm confused by a lot of your comments, but I think they're trying to revert back to the old version before we reduced fees? |
@rnicoll See my comment on their first suggestion. Yes, you are correct. He is working from an old branch. |
@rnicoll If you could explain to me, offline, how to compute all the fees and how the test framework works I can take care of all these erros. |
I think I've fixed the errors, next problem is the values in af5e7b6 are very slightly lower than I'd expect. I'd expected:
It's likely the transactions are a byte bigger than I've expected, but not sure. If you have the energy to calculate the amounts taking into account transaction actual size, it would be appreciated. |
@rnicoll Even if for my own reference, I would very much like to understand all the fees. Who pays them, who receives them, when, how, and why. A chart and an explanation would allow me to fly through fixing RPC errors, now and in the future. Or just a chat about them. |
@ReverseControl You've seen #2347 right? Basics, in the fees from 1.14.5:
There's then weird corner cases like relay required fees and block inclusion and free transaction space, but the above covers 99% of cases. |
@rnicoll Yes, I have read that. So, questions:
The corner cases are the most interesting cases, because those are the ones we have to absolutely get right. |
@ReverseControl Relay fees go to the miners, they're just minimums that nodes use to decide if to relay. The idea is that nodes don't bother to relay anything that wouldn't be mined (because it's just network spam), rather than they're paid to the relaying nodes. Dust limit is the amount below which an output is considered ridiculously small. Typically any change below dust is just given to the miner as additional fee, because the output isn't worth the data to store it. The sender owns the change address. There's a much longer write up on change addresses at https://support.blockchain.com/hc/en-us/articles/360018566291-Change-addresses |
@rnicoll Nodes do not have coins, who pays the relaying fee to the miners? Good to know what dust limit is and how it is used. I took a look at the link. That makes more sense. |
@ReverseControl Relay fees is just a threshold value, it's not its own fee type. So they're a value which the fee paid by the sender to the miner must exceed, for nodes to be prepared to relay the transaction. That make any sense? |
@rnicoll I think I understand, so in your first bullet example: the fee paid by the sender is |
Very close - relay fee is also in DOGE per kilobyte, so for a 0.225kB tx and a relay fee of 0.001 DOGE per kilobyte, the fee for the transaction must be at least 0.000225 (yes 1/10th of the fee used) for it to be relayed. So in your example if it was below 0.0009 DOGE it wouldn't be relayed. |
@rnicoll You mean So, in essence so long as |
Yes to 0.0009, sorry. |
@rnicoll @patricklodder Where are all the methods of |
@rnicoll @patricklodder what is WITNESS_SCALE_FACTOR? What is it used for? Also, what is DEFAULT_BYTES_PER_SIGOP? What is it used for? |
|
Those are the RPC methods, you can see them with |
It's basically any of the RPC commands: https://developer.bitcoin.org/reference/rpc/ Practically speaking, best way to find how to call them from Python is to |
@rnicoll I found the ghosting byte. As far as I can tell, this is a nondeterministic error. Long story short, the missing byte disappears in the real signature of a transaction. For reference:
The computed https://github.com/rnicoll/dogecoin/blob/1.14.5-fees/src/wallet/wallet.cpp#L2752 The transaction above, after the function call is done executing, is shorter by one byte than the transaction below, the real signing, with some frequency, i.e. this is not deterministic: https://github.com/rnicoll/dogecoin/blob/1.14.5-fees/src/wallet/wallet.cpp#L2646 . And this latter is the one used to compute the fee by the wallet, while the former and valid/real-signed one is the one that is stored in the wallet, and the one that Python later retrieves via RPC calls. Which is why, we both compute fees off by one byte on occasion. Question is: Shouldn't signatures be fixed length all the time under every imaginable circumstance? Edit 1: Added emphasis where the ghosting byte actually goes ghosting. |
No. This is a known "feature", as was also discussed under #2441. It can be prevented by implementing low-R signing, which means you sign in a loop, until you hit an R value that is low enough to fit in the smaller byte array, and then you use that. It is part of the bitcoin baseline used for 1.21, I think. |
@patricklodder I do not see any discussion in #2441 on this. I am not familiar with these types of signatures. A paper reference would be nice. What would you suggest as a fix for this issue of not having the correct fee value? |
@ReverseControl That makes sense, and I think we're probably okay then. Aware this may not be all of the changes, but hoping we can start the review cycle at least. |
|
@ReverseControl That makes sense, and I think we're probably okay then. I've done some tests and certainly actual tx length and length used when calculating fee aren't necessarily the same, but at least got that nailed down. |
@rnicoll Though a priority it might not be, given the monetary cost is so minimal, I am rather pedantic about details like this; that is, doing things correctly in the strictest logical sense of the word correct. Would it not be appropriate to fix this issue by first signing the transaction for real and then calculating the fee with the actual transaction that will be recorded in the blockchain? As opposed to making assumptions, calculating the fee, and then signing the transaction that will become the legitimate transaction after the fact. |
That's the issue - we can't know the fee until after signing, and we can't update the fee after signing without breaking the signature. Instead we use a fee value which is long enough to cover the biggest signature we can expect. |
* Reduce DEFAULT_FALLBACK_FEE to 1,000,000 Koinu. Note this by itself has no effect as the required fee is higher. * Reduce wallet minimum fees to 0.01 DOGE * Update DEFAULT_DUST_LIMIT * Revise derived values after updating recommended fees * Remove fee rounding from RPC tests * Revert tests back to Bitcoin originals where possible
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.
oof. Pretty sure this is good to go. Lots of math to follow but - seems sane.
Opening this early so if people are looking at fees, we have a single branch to stage on.