-   Notifications  
You must be signed in to change notification settings  - Fork 2.2k
 
TransactionBuilder: add fee safety #696
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
| } | ||
|   |  ||
| TransactionBuilder.prototype.__addInputUnsafe = function (txHash, vout, sequence, scriptSig, prevOutScript) { | ||
| TransactionBuilder.prototype.__addInputUnsafe = function (txHash, vout, options) { | 
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.
Maybe this is how we should handle addInput universally for SegWit and the upcoming changes?
 Looks like a good balance of positional and named IMHO
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.
indeed, looks good!
| txb.__addInputUnsafe(txIn.hash, txIn.index, { | ||
| sequence: txIn.sequence, | ||
| script: txIn.script | ||
| }) | 
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.
I could probably just pass txIn here as options, haha
   src/transaction_builder.js  Outdated    
 |   |  ||
| // its not fool-proof, but, it might help somebody | ||
| // fee > 0.2BTC | ||
| return fee > (0.2 * 1e8) | 
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.
Should this be TransactionBuilder.ABSURD_FEE or similar?
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.
I also don't think anything beyond a hard-coded constant is reasonable without being annoying in actual use cases
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.
Also, is this value suitable?
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.
- 👍 for exporting the constant.
 - Not sure if it's suitable at all :D
 
If it's not a requirement to provide a value, it seems fee can be negative which would cause the function to declare an absurd fee. Is it intended to introduce this behavior in here? https://github.com/bitcoinjs/bitcoinjs-lib/pull/696/files#diff-52af0f8b5da51627aa8d01193636ba73R384
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.
it seems fee can be negative which would cause the function to declare an absurd fee
What? How?
 The fee can be negative, but that is fine. It will still return false as it it less than absurd.
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.
Oops, my mistake
| BIP32Path.toJSON = function () { return 'BIP32 derivation path' } | ||
|   |  ||
| var SATOSHI_MAX = 2.1 * 1e15 | ||
| var SATOSHI_MAX = 21 * 1e14 | 
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.
This was annoying me
| "exception": "Transaction w/ absurd fees", | ||
| "inputs": [ | ||
| { | ||
| "txHex": "01000000000100e1f505000000000000000000", | 
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.
Smallest transaction I've ever seen
|   ping @afk11 for ACK/NACK  |  
| } | ||
|   |  ||
| TransactionBuilder.prototype.__addInputUnsafe = function (txHash, vout, sequence, scriptSig, prevOutScript) { | ||
| TransactionBuilder.prototype.__addInputUnsafe = function (txHash, vout, options) { | 
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.
indeed, looks good!
   src/transaction_builder.js  Outdated    
 | if (!this.tx.outs.length) throw new Error('Transaction has no outputs') | ||
|   |  ||
| // do not rely on this, its merely a last resort | ||
| if (this.__hasAbsurdFee()) throw new Error('Transaction has absurd fees') | 
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.
Is there any way to disable this?
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.
No, but why would you?
 This is assuming you are building a "final" transaction.
 There is never a case where this isn't suitable?
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.
The fee wouldn't be absurd if the transaction is very large, or you really want it to confirm. It feels it should be possible without setting allowIncomplete = true
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.
@afk11 if you're doing 150kb transactions 120 satoshis/byte, only then, will you hit this limit.
 With a constant TransactionBuilder.ABSURD_FEERATE, a user could change that to by-pass these limits themselves, as they will be a very select few people.
   src/transaction_builder.js  Outdated    
 |   |  ||
| // its not fool-proof, but, it might help somebody | ||
| // fee > 0.2BTC | ||
| return fee > (0.2 * 1e8) | 
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.
- 👍 for exporting the constant.
 - Not sure if it's suitable at all :D
 
If it's not a requirement to provide a value, it seems fee can be negative which would cause the function to declare an absurd fee. Is it intended to introduce this behavior in here? https://github.com/bitcoinjs/bitcoinjs-lib/pull/696/files#diff-52af0f8b5da51627aa8d01193636ba73R384
|   I guess my questions are: 
  |  
 
 In the cases where you wouldn't want it (incomplete transactions), it is avoided by using  
 No? Its optional obviously. 
 We have the signatures at this point, so it should be straight forward to use fee rate instead.  |  
 
  |  
|   The assumptions this makes is: 
 If we have any input values, and their sum is larger than the outgoing, we can determine the minimum fee for the transaction (not the actual fee, the minimum). At that point, we can say, if the minimum is absurd, it doesn't matter what the rest of the inputs are, because they only make it worse. Naturally, in most cases, the [detected] minimum fee for the transaction is negative, because   |  
|   I think an absurd fee rate of >1000 satoshis per byte is a good limit for now. We could easily adjust it up-wards in patch releases.  |  
|   The only remaining part of the TODO for this PR is: 
 Personally, I can't decide if this is a good or a bad thing... so I'm going to leave it to a patch PR later rather than do it.  |  
|   Merging once Travis passes.  |  
|   ACK 6a019ee  |  
edit: For future reference, the merged constant is a maximum, minimum fee-rate, of 1000 satoshis per byte.