Round-trip the PoWLimit through the compact representation

`zcashd` converts the PoWLimit into a compact representation before
using it to perform difficulty filter checks.

The Zcash specification converts to compact for the default difficulty
filter, but not for testnet minimum difficulty blocks. (ZIP 205 and
ZIP 208 don't specify this conversion either.) See #1277.
This commit is contained in:
teor 2020-11-11 00:48:50 +10:00
parent 8f838166a8
commit b2a9ea62fe
2 changed files with 48 additions and 1 deletions

View File

@ -280,7 +280,16 @@ impl ExpandedDifficulty {
Network::Testnet => (U256::one() << 251) - 1,
};
limit.into()
// `zcashd` converts the PoWLimit into a compact representation before
// using it to perform difficulty filter checks.
//
// The Zcash specification converts to compact for the default difficulty
// filter, but not for testnet minimum difficulty blocks. (ZIP 205 and
// ZIP 208 don't specify this conversion either.) See #1277 for details.
ExpandedDifficulty(limit)
.to_compact()
.to_expanded()
.expect("difficulty limits are valid expanded values")
}
/// Calculate the CompactDifficulty for an expanded difficulty.

View File

@ -318,6 +318,44 @@ fn block_difficulty() -> Result<(), Report> {
Ok(())
}
/// Test that the genesis block threshold is PowLimit
#[test]
fn genesis_block_difficulty() -> Result<(), Report> {
genesis_block_difficulty_for_network(Network::Mainnet)?;
genesis_block_difficulty_for_network(Network::Testnet)?;
Ok(())
}
#[spandoc::spandoc]
fn genesis_block_difficulty_for_network(network: Network) -> Result<(), Report> {
zebra_test::init();
let block = match network {
Network::Mainnet => zebra_test::vectors::MAINNET_BLOCKS.get(&0),
Network::Testnet => zebra_test::vectors::TESTNET_BLOCKS.get(&0),
};
let block = block.expect("test vectors contain the genesis block");
let block = Block::zcash_deserialize(&block[..]).expect("block test vector should deserialize");
let hash = block.hash();
/// SPANDOC: Calculate the threshold for the genesis block {?network}
let threshold = block
.header
.difficulty_threshold
.to_expanded()
.expect("Chain blocks have valid difficulty thresholds.");
/// SPANDOC: Check the genesis PoWLimit {?network, ?threshold, ?hash}
{
assert_eq!(threshold, ExpandedDifficulty::target_difficulty_limit(network),
"genesis block difficulty thresholds must be equal to the PoWLimit");
}
Ok(())
}
/// Test ExpandedDifficulty ordering
#[test]
#[spandoc::spandoc]