Skip to content

Conversation

@lowhung
Copy link
Collaborator

@lowhung lowhung commented Oct 27, 2025

Implements #301 (and #257)

What this PR does:

  • Combines the byte_array.rs hash macros with the hash.rs file as these had some overlap
  • Create PoolId, KeyHash, VrfKeyHash and other keys to use this fixed bytes type

…ash` utility across modules. Includes updates for serialization, type conversions, and tests.
@lowhung lowhung marked this pull request as draft October 27, 2025 18:45
…ross pool-related operations and update associated tests
…nual conversions across modules, and adjust types for stronger consistency. Update tests and documentation accordingly.
…r cleanup. Refactor `POOL_KEY_LENGTH` to `POOL_ID_LENGTH`
…stency, update associated type aliases, imports, and serialization logic.
@lowhung lowhung marked this pull request as ready for review October 28, 2025 23:11
…s, update imports, and adjust serialization logic across modules for consistency.
@lowhung lowhung force-pushed the lowhung/unify-hash-types branch from 2551bd4 to fb77f49 Compare October 29, 2025 00:32
…s, update imports, and adjust serialization logic across modules for consistency.
pub fn keyhash_256(key: &[u8]) -> KeyHash {
///
/// Returns a 32-byte hash.
pub fn keyhash_256(key: &[u8]) -> Hash<32> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make more sense to name this function with its hash function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see, so define this as a method on the Hash type itself?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@golddydev and I spoke, and we'll address in this in a follow-up PR. Basically, create specific types for a blake2b_256 + blake2b_224

… redundant `declare_hash_newtype_with_bech32!`, and update associated imports and Bech32 serialization logic.
# Conflicts:
#	modules/governance_state/src/state.rs
…ting_mainnet_up_573`, and update `conway_verification.csv` with new governance actions.
@lowhung lowhung force-pushed the lowhung/unify-hash-types branch from 905a28e to 28cbe9d Compare October 29, 2025 17:28
@lowhung lowhung changed the base branch from main to lowhung/introduce-combined-hash-file October 29, 2025 18:31
…y-hash-types

# Conflicts:
#	codec/src/map_parameters.rs
#	common/src/hash.rs
#	common/src/snapshot/pool_params.rs
#	common/src/snapshot/streaming_snapshot.rs
#	common/src/types.rs
#	modules/chain_store/src/chain_store.rs
#	modules/chain_store/src/stores/fjall.rs
#	modules/chain_store/src/stores/mod.rs
#	modules/epochs_state/src/state.rs
#	modules/genesis_bootstrapper/src/genesis_bootstrapper.rs
#	modules/mithril_snapshot_fetcher/src/mithril_snapshot_fetcher.rs
#	modules/tx_unpacker/src/tx_unpacker.rs
#	modules/upstream_chain_fetcher/src/body_fetcher.rs
@lowhung lowhung force-pushed the lowhung/unify-hash-types branch from 7c730cc to 410f572 Compare October 30, 2025 00:14
Base automatically changed from lowhung/introduce-combined-hash-file to main October 30, 2025 15:16
# Conflicts:
#	modules/historical_accounts_state/src/immutable_historical_account_store.rs
Copy link
Collaborator

@sandtreader sandtreader left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, feels so much better to have things properly typed.

Only comments are whether the various calls to bech_32/HRP functions could use the Hash types' own ones now, or if they don't exist yet, could they be extended so that each type knows its HRP prefix rather than having lots of different code that repeats them.

impl Default for ShelleyAddressPaymentPart {
fn default() -> Self {
Self::PaymentKeyHash(Vec::new())
Self::PaymentKeyHash([0u8; 28].into())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not (or could be) covered by a default()?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done here

/// Payment to a script
#[n(1)]
ScriptHash(#[n(0)] ScriptHash),
ScriptHash(#[n(0)] KeyHash),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have we lost ScriptHash as a separate type? This seems like a regressive step (although I may have misunderstood)

Copy link
Collaborator Author

@lowhung lowhung Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it back here, but it's just an aliased type on KeyHash which is a Hash<28>.

StakeAddress {
network: NetworkId::Mainnet,
credential: StakeCredential::AddrKeyHash(vec![0u8; 28]),
credential: StakeCredential::AddrKeyHash([0u8; 28].into()),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KeyHash::default() again?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done here

}

pub fn from_drep_bech32(bech32_str: &str) -> Result<Self, anyhow::Error> {
pub fn from_drep_bech32(bech32_str: &str) -> Result<Self, Error> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we not have bech32 encode/decode in the macro-defined Hash types now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do! However these are implemented on the Credential struct, so the result is different vs Hash<N> types.

Voter::DRepKey(k) => write!(f, "{}", self.to_bech32("drep", k)),
Voter::DRepScript(s) => write!(f, "{}", self.to_bech32("drep_script", s)),
Voter::StakePoolKey(k) => write!(f, "{}", self.to_bech32("pool", k)),
Voter::DRepKey(k) => write!(f, "{}", self.to_bech32("drep", k.as_ref())),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these were typed, wouldn't they know how do bech32 anyway?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point, we could define hash types for those as well so their to_bech32() is cleaner.

I've been looking at this quite a bit recently https://cips.cardano.org/cip/CIP-0005

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, Voter should have a to_bech32(&self) -> Result<String, _> and the Display impl should call that. Would be unfortunate to let an error string like <invalid: blah> propagate around where a bech32-encoded address is expected

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeh...that's a great point. I'll do that 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated this here d181f1c

@@ -1,23 +1,23 @@
gov_action1zhuz5djmmmjg8f9s8pe6grfc98xg3szglums8cgm6qwancp4eytqqmpu0pr,15f82a365bdee483a4b03873a40d3829cc88c048ff3703e11bd01dd9e035c916,0,,100000000000,45dee6ee5d7f631b6226d45f29da411c42fa7e816dc0948d31e0dba7,507,,Information,"{""deposit"":100000000000,""reward_account"":{""network"":""Mainnet"",""payload"":{""StakeKeyHash"":""45dee6ee5d7f631b6226d45f29da411c42fa7e816dc0948d31e0dba7""}},""gov_action_id"":{""transaction_id"":""15f82a365bdee483a4b03873a40d3829cc88c048ff3703e11bd01dd9e035c916"",""action_index"":0},""gov_action"":""Information"",""anchor"":{""url"":""ipfs://QmWjcHsrq9kKHZZ7aPPFjqN6wLuxH9d8bcqssmrE7H4cvb"",""data_hash"":""2f98f57c4149fdfed2b73cbd821226fe417ef5ed49d8f836a37b31edf14dea47""}}",,,,,Some(514),cy2/n0/a1:dy8971134676473/n220807337570898/a28653074063371:sy156770300966308/n1482461784403994/a27102517904169,c0:d1:s1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this shoiuld be in this PR, even if it makes the CI pass

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I'll unstage this 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unstaged af62ad8

Copy link
Collaborator

@whankinsiv whankinsiv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! There are a few places we can further clean the types up.

ShelleyAddressDelegationPart::None => (&Vec::new(), 3),
ShelleyAddressDelegationPart::StakeKeyHash(hash) => (hash, 0),
ShelleyAddressDelegationPart::ScriptHash(hash) => (hash, 1),
let (delegation_hash, delegation_bits): (Vec<u8>, u8) = match &self.delegation {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delegation_hash here can be Hash<28> to avoid the to_vec() conversion below.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the situation where we have no delegation part, do you know what the hash would resolve to?

Copy link
Collaborator

@whankinsiv whankinsiv Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding if the delegation part is missing it is not included in the data to be Bech32 encoded.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll resolve this in a follow-up PR 👍

ActiveStakes(u64),
/// Vec<(PoolId, StakeKey, ActiveStakeAmount)>
SPDDByEpoch(Vec<(KeyHash, KeyHash, u64)>),
SPDDByEpoch(Vec<(PoolId, KeyHash, u64)>),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be StakeAddress instead of KeyHash?


/// Get Pool Delegators
pub fn get_pool_delegators(&self, pool_operator: &KeyHash) -> Option<Vec<(KeyHash, u64)>> {
pub fn get_pool_delegators(&self, pool_operator: &PoolId) -> Option<Vec<(KeyHash, u64)>> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return Option<Vec<(StakeAddress, Lovelace)>>

@lowhung lowhung force-pushed the lowhung/unify-hash-types branch from be9c38d to 0dc9c03 Compare October 31, 2025 00:14
@lowhung lowhung force-pushed the lowhung/unify-hash-types branch from bae3fe5 to 13c515a Compare October 31, 2025 00:49
@lowhung lowhung force-pushed the lowhung/unify-hash-types branch from 13c515a to 064e38b Compare October 31, 2025 00:49
@lowhung
Copy link
Collaborator Author

lowhung commented Oct 31, 2025

I will address the rest of @whankinsiv comments re: StakeAddress in a follow-up PR 👍

Copy link
Collaborator

@whankinsiv whankinsiv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for implementing these changes. Looking forward to the follow up PR with the KeyHash -> StakeAddress refactor.

# Conflicts:
#	modules/accounts_state/src/verifier.rs
#	modules/historical_accounts_state/src/immutable_historical_account_store.rs
@lowhung lowhung merged commit 0b69ae2 into main Oct 31, 2025
2 checks passed
@lowhung lowhung deleted the lowhung/unify-hash-types branch October 31, 2025 15:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants