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
Add chain hash type using consts #878
Add chain hash type using consts #878
Conversation
Concept NACK. Nothing in LN requires chain hash to be a genesis block hash. For instance in RGB we use chain hash to be an client-side asset id. |
I'm not quite understanding why you ack'ed #872 and nack'ed this one, they both use genesis block as the basis for the chain hash? Am I missing something? Also, BOLT 0 specifies that the chain hash for Bitcoin mainnet must be the hash of the genesis block (https://github.com/lightningnetwork/lightning-rfc/blob/ffeece3dab1c52efdb9b53ae476539320fa44938/00-introduction.md#chain_hash). Would you prefer if we added a call to |
1b40081
to
ef802f1
Compare
Implements |
@tcharding LN BOLTs authors had no idea that there might be use cases for assets which operate not on the level of blockchain. However, by the nature of LN to be a multi-asset network, #872 allows use of custom hash values for |
Oh, I see, I left out the call to |
f7a451e
to
182fe2e
Compare
I think genesis block here is more relevant, since multiple assets can operate the same network (like in Liquid), while genesis block hash is definitely a for of the native asset id for the network, which is the only one |
7e59d6c
to
03d5dff
Compare
/// The uniquely identifying hash of the target blockchain. | ||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
pub struct ChainHash([u8; 32]); | ||
impl_array_newtype!(ChainHash, u8, 32); |
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 we can use the approach you proposed in #870 just to avoid forgetting to re-base that PR after this one got merged?
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 fully happy with #870, that's why I ended up using impl_array_newtype
so that this one is in line with the current code.
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.
My personal preference will be to have genesis hashes taken from genesis blocks by the means of const functions, not hex values, which are hard to validate
While conceptually feasible, converting |
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 03d5dff
@tcharding has convinced me :)
src/blockdata/constants.rs
Outdated
@@ -176,15 +176,47 @@ pub fn genesis_block(network: Network) -> Block { | |||
} | |||
} | |||
|
|||
// Mainnet value can be verified at https://github.com/lightning/bolts/blob/master/00-introduction.md | |||
const CHAIN_HASH_BITCOIN: &str = "6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000"; |
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: these constants ideally should be byte arrays (while in the test module there should be the hex constant to verify)
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 nice, that's heaps better than parsing the hex strings, 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.
I changed the const names to GENESIS_BLOCK_HASH_BITCOIN
also.
13e7608
to
25f3ef4
Compare
Please re-review, force push makes considerable changes as suggested by @RCasatta (incl. change of const names). |
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 left a small nit that is non-merge blocking. For future reference concerning my reviews, whenever I nit
something, it is always non-merge blocking.
Other maintainers are free to go ahead and the PR. The author can ignore or decide the comment based on a case of case basis. (length of PR, urgency, number of existing ACKs, available time etc).
@@ -176,6 +176,33 @@ pub fn genesis_block(network: Network) -> Block { | |||
} | |||
} | |||
|
|||
// Mainnet value can be verified at https://github.com/lightning/bolts/blob/master/00-introduction.md |
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: I would rather have this bitcoin core source than a lighting spec. But it's okay.
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 this even part of Bitcoin Core? From my understanding this is a LN and DLC thing.
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 Genesis block? I think that's a Bitcoin thing :)
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.
lol, I meant that chain hash is a LN/DLC thing and the LN spec says that the identifier for mainnet is the hash of the genesis block - hence I linked to the LN spec.
@sanket1729 would you prefer that this comment explained what the value used is but then linked to the bitcoin core source for the actual 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.
I am okay without a comment here. But I have a slight preference to link to the bitcoin core source. When reading a constant GENESIS_BLOCK_HASH_BITCOIN
in file src/blockdata/constants
in rust-bitcoin
, I would expect it to be a bitcoin thing. It would feel odd that I need to check a lightning spec to double-check that the bitcoin genesis block is correct.
ChainHash functions can link to lightning spec if needed.
src/blockdata/constants.rs
Outdated
const GENESIS_BLOCK_HASH_BITCOIN: [u8; 32] = [0, 0, 0, 0, 0, 25, 214, 104, 156, 8, 90, 225, 101, 131, 30, 147, 79, 247, 99, 174, 70, 162, 166, 193, 114, 179, 241, 182, 10, 140, 226, 111]; | ||
const GENESIS_BLOCK_HASH_TESTNET: [u8; 32] = [0, 0, 0, 0, 9, 51, 234, 1, 173, 14, 233, 132, 32, 151, 121, 186, 174, 195, 206, 217, 15, 163, 244, 8, 113, 149, 38, 248, 215, 127, 73, 67]; | ||
const GENESIS_BLOCK_HASH_SIGNET: [u8; 32] = [0, 0, 0, 8, 129, 152, 115, 233, 37, 66, 44, 31, 240, 249, 159, 124, 201, 187, 178, 50, 175, 99, 160, 119, 164, 128, 163, 99, 59, 238, 30, 246]; | ||
const GENESIS_BLOCK_HASH_REGTEST: [u8; 32] = [15, 145, 136, 241, 60, 183, 178, 199, 31, 42, 51, 94, 58, 79, 195, 40, 191, 91, 235, 67, 96, 18, 175, 202, 89, 11, 26, 17, 70, 110, 34, 6]; |
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.
AFAIR, there were some complaints exposing these as public constants. #568. But I like the way you have done it here.
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.
Unrelated to this PR:
Maybe we should use Network::genesis_hash(&self)
API?
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.
AFAIR, there were some complaints exposing these as public constants. #568. But I like the way you have done it here.
Thanks for the link. I think this PR is ok according to that discussion, specifically:
- These consts are not public
- They are defined in
constants.rs
- All networks are covered not just mainnet
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 we should use
Network::genesis_hash(&self)
API?
We did that in #872 but after review decided to optimize and use const byte arrays with unit tests to verify them.
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.
Separate PRs because I open two alternate solutions in parallel.
In the referenced document https://github.com/lightning/bolts/blob/master/00-introduction.md we have:
while we are using reversed hex encoding like BlockHash. eg. the following test fails
|
Legend for catching that @RCasatta! I spent so much time on the first versions making sure that was correct and then dropped the ball when adding the byte arrays. Thanks man. |
Legend for catching that @RCasatta! I spent much time on the first versions making sure that was correct and then dropped the ball when adding the byte arrays. Thanks man. EDIT: PR now includes your unit test. |
25f3ef4
to
76166ac
Compare
I ended up [ab]using a |
I start thinking that this is very LN-specific and probably should not be a part of |
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.
LGTM. I agree with Dr Orlovsly that we don't want lightning-specific things here, but this isn't - this is a new way of accessing the Genesis block in rust-bitcoin, that works without allocating and without doing the hashing. Whether this needs a whole type to represent it, and whether that type needs to be in rust-bitcoin...I kinda don't think so, but I also don't really care/feel strongly about it.
const GENESIS_BLOCK_HASH_SIGNET: [u8; 32] = [246, 30, 238, 59, 99, 163, 128, 164, 119, 160, 99, 175, 50, 178, 187, 201, 124, 159, 249, 240, 31, 44, 66, 37, 233, 115, 152, 129, 8, 0, 0, 0]; | ||
const GENESIS_BLOCK_HASH_REGTEST: [u8; 32] = [6, 34, 110, 70, 17, 26, 11, 89, 202, 175, 18, 96, 67, 235, 91, 191, 40, 195, 79, 58, 94, 51, 42, 31, 199, 178, 183, 60, 241, 136, 145, 15]; | ||
|
||
/// The uniquely identifying hash of the target blockchain. |
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 we just say this is the Genesis hash?
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 is not restricted to being the genesis block hash (according to #878 (comment)). Re-reading that comment made me think that the word 'hash' shouldn't even be in the comment but then its in the type name so ¯\_(ツ)_/¯
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 it should be AssetId
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.
If we use AssetId
then this is no longer anything to do with the LN spec's chain hash. Perhaps this comment, along with @TheBlueMatt's observation that this PR is just a new way of getting the genesis block without hashing implies that we should not add the ChainHash
type at all and just expose a way for folk to get the genesis block without hashing so they can use it if they wish to create a ChainHash
type themselves?
/// | ||
/// See [BOLT 0](https://github.com/lightning/bolts/blob/ffeece3dab1c52efdb9b53ae476539320fa44938/00-introduction.md#chain_hash) | ||
/// for specification. | ||
pub fn using_genesis_block(network: Network) -> Self { |
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.
Would impl From
be too unreadable?
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 think from discussion above we want to make it explicit that we are using the genesis block.
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 76166ac
There are some nits but feel free to merge, I don't care.
fn regtest_chain_hash_genesis_block() { | ||
let (got, want) = chain_hash_and_genesis_block(Network::Regtest); | ||
assert_eq!(got, want); | ||
} |
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.
Use a macro to deduplicate? And perhaps move assert_eq
to the common function.
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.
Done, cheers!
src/blockdata/constants.rs
Outdated
|
||
// The *_chain_hash tests are sanity/regression tests, they verify that the const byte array | ||
// representing the genesis block is the same as that created by hashing the genesis block. | ||
fn chain_hash_and_genesis_block(network: Network) -> (String, String) { |
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.
A comment explaining why we stringly compare would be useful for future readers eager to clean it up.
As we do for the rest of the macros use the fully qualified path to `fmt` so users of the macro do not have to import it.
Import with wildcard is applicable in unit tests, use it.
The Lightning network defines a type called 'chain hash' that is used to uniquely represent the various Bitcoin networks as a 32 byte hash value. Chain hash is now being used by the DLC folks, as such it is useful to have it implemented in rust-bitcoin. One method of calculating a chain hash is by hashing the genesis block for the respective network. Add a `ChainHash` type that can be used to get the unique identifier of each of the 4 Bitcoin networks we support. Add a method that returns the chain hash for a network using the double sha256 of the genesis block. Do so using hard coded consts and add unit tests (regression/sanity) that show these hard code byte arrays match the hash of the data we return for the genesis block for the respective network. The chain hash for the main Bitcoin network can be verified from LN docs (BOLT 0), add a link to this document.
76166ac
to
8e29f2b
Compare
Implemented @Kixunil's suggestions and rebased. |
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 8e29f2b
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 8e29f2b.
LGTM, I still have a very slight preference to link to bitcoin hash values instead of lightning spec. But I can live it. 8e29f2b#r877663661
8e29f2b Add ChainHash type (Tobin Harding) cd8f511 blockdata: constants: Use wildcard import in unit tests (Tobin Harding) 71bf196 Use fully qualified path in macro (Tobin Harding) Pull request description: The Lightning network defines a type called 'chain hash' that is used to uniquely represent the various Bitcoin networks as a 32 byte hash value. Chain hash is now being used by the DLC folks, as such it is useful to have it implemented in rust-bitcoin. One method of calculating a chain hash is by hashing the genesis block for the respective network. Add a `ChainHash` type that can be used to get the unique identifier of each of the 4 Bitcoin networks we support. Add a method that calculates the chain hash for a network using the double sha256 of the genesis block. Do so using hard coded consts and add unit tests (regression/sanity) that show these hard coded byte arrays match the hash of the data we return for the genesis block for the respective network. The chain hash for the main Bitcoin network can be verified from LN docs (BOLT 0), add a link to this document. Closes: #481 ACKs for top commit: Kixunil: ACK 8e29f2b sanket1729: ACK 8e29f2b. Tree-SHA512: 8156bb55838b73694ddf77a606cbe403f53a31d363aa0dee11b97dc31aa9b62609d7d84b8f0f92c08e90372a3e8c7b416fb07989d6da9633763373b41339b1f5
The Lightning network defines a type called 'chain hash' that is used to uniquely represent the various Bitcoin networks as a 32 byte hash value. Chain hash is now being used by the DLC folks, as such it is useful to have it implemented in rust-bitcoin.
One method of calculating a chain hash is by hashing the genesis block for the respective network.
Add a
ChainHash
type that can be used to get the unique identifier of each of the 4 Bitcoin networks we support. Add a method that calculates the chain hash for a network using the double sha256 of the genesis block. Do so using hard coded consts and add unit tests (regression/sanity) that show these hard coded byte arrays match the hash of the data we return for the genesis block for the respective network.The chain hash for the main Bitcoin network can be verified from LN docs (BOLT 0), add a link to this document.
Closes: #481