-
Notifications
You must be signed in to change notification settings - Fork 377
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
[RFC][Tx Sort] Implement sorting of inputs #84
Conversation
Follows BIP69: https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki 1. Implements sorting of transactoin inputs. - BIP says to use "reversed byte-order" for the `prev_hash`. I interpreted this as: little-endian. - TODO need to add tests 2. Re: improve sorting of TxOut's script_pubkey to use lexicographic ordering, and not length. From the test-cases i've included it seems that the current code already does lexicographic ordering (and not length based). Am i missing something?
Cool, thanks. Can you add the test vectors from the BIP (and add some test vectors to the BIP that test variable-length scriptPubKeys)? |
@TheBlueMatt sure, yeah happy to, but I've been running into some issues. For example, the given values in the BIP don't seem to serialize-deserialize cleanly. See the test output at the bottom of https://gist.github.com/savil/d6acec10aa5a8ea6698fbb19443d68cb. Not yet sure if that indicates a bug in the hex-string or in the rust-bitcoin's serialize/deserialize implementation. Also, looks like |
Weird, is it a 0-input transaction (rust-bitcoin/rust-bitcoin#104) cause then the BIP would need updating? Generally I've been using the hex_bytes from bitcoin::util::misc in tests, but I probably should have been using from_hex. |
@TheBlueMatt hmm, I need to learn BitcoinScript :p. Can you tell if they are 0-input from the info below?
EDIT: I made a copy-pasta error in the first hex-string above. Fixed it now. |
Ohoh, sorry, I misread. So your problem is you're trying to deserialize the script with a length byte, but the script in the BIP does not have its length byte included. You want to just convert the hex string to a Vec and do Script::from(). |
Also note current patch uses spaces instead of tabs in the tests mod. We really need editor configs in these files.... |
thank you. Didn't work for me, though. The code I have is:
(sorry, I incorrectly pointed out the errant line in my previous gist up top) |
@savil |
@yuntai much obliged, thanks! |
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.
Probably needs a BIP/BOLT update here first either way.
src/util/transaction_utils.rs
Outdated
Ordering::Greater | ||
} else { | ||
Ordering::Equal | ||
} | ||
}); | ||
} | ||
|
||
// TODO savil. Add tests. |
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.
Cool, so still need the tests added here.
updated with BIP69 test cases.
@TheBlueMatt why is variable-length the important property to focus on? I agree we need to augment BIP69 spec to have a test case where the output values are the same. |
Cargo.toml
Outdated
@@ -20,6 +20,7 @@ bitcoin = "0.13" | |||
rust-crypto = "0.2" | |||
rand = "0.4" | |||
secp256k1 = "0.9" | |||
hex = "0.3.2" |
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'll make this test-only
I'm not actually sure if we ever call sort_outputs with different-length scripts, but if we do sort_outputs is clearly wrong - Rust's comparison will sort first by length, then by contents, whereas the BIP seems to (but doesn't actually explicitly say) that you should sort first by contents, then by length, as if by memcmp. Hence my comment that the BIP is underspecifed and needs to be fleshed out, with more test vectors added to it. |
But, given the BIP is generally a terrible idea for anything but Lightning, I'd really strongly prefer we update the BOLT to be specified, and not reference the BIP at all. |
|
||
let txout2 = TxOut { | ||
value: 100, | ||
script_pubkey: Builder::new().push_int(1).push_int(2).into_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'm not actually sure if we ever call sort_outputs with different-length scripts,
@TheBlueMatt I'm confused. Does this test-case not exercise different-length scripts? if not, could you advise me on how to construct a different-length 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.
Oh, indeed, sorry I missed that, somehow I concluded Rust's comparison did something different.
@@ -27,3 +27,6 @@ gcc = "0.3" | |||
[dev-dependencies.bitcoin] | |||
version = "0.13" | |||
features = ["bitcoinconsensus"] | |||
|
|||
[dev-dependencies] | |||
hex = "0.3.2" |
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'm generally fine with this, but now we've got two ways of doing hex - using rust-bitcoin's utils one, and this. It probably makes sense to convert them all to the hex crate, cause using an exported rust-bitcoin util method always felt strange to me.
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, not gonna block on this, but would be nice to fix in a followup PR.
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.
ack, I'll look into it after I wrap up rust-bitcoin/rust-bitcoin#107
|
||
use bitcoin::blockdata::script::{Script, Builder}; | ||
use bitcoin::blockdata::transaction::TxOut; | ||
use bitcoin::util::hash::Sha256dHash; |
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.
There's a few tab/space things in the diff here - I always set my editor to auto-detect whether it should use tabs or spaces based on the file, and also highlight tabs and spaces differently so they're instantly visible.
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.
crap. thought I'd fixed all of these. My apologies.
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 big deal, I'm generally happy to clean up simple stuff like that post-merge (see 7f46025)
Follows BIP69: https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki
prev_hash
. I interpreted this as: little-endian.From the test-cases i've included it seems that the current code already does lexicographic ordering (and not length based). Am i missing something?