Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions codec/src/map_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,9 @@ pub fn map_address(address: &addresses::Address) -> Result<Address> {

addresses::Address::Stake(stake_address) => Ok(Address::Stake(StakeAddress {
network: map_network(stake_address.network())?,
payload: match stake_address.payload() {
addresses::StakePayload::Stake(hash) => {
StakeAddressPayload::StakeKeyHash(hash.to_vec())
}
addresses::StakePayload::Script(hash) => {
StakeAddressPayload::ScriptHash(hash.to_vec())
}
credential: match stake_address.payload() {
addresses::StakePayload::Stake(hash) => StakeCredential::AddrKeyHash(hash.to_vec()),
addresses::StakePayload::Script(hash) => StakeCredential::ScriptHash(hash.to_vec()),
},
})),
}
Expand All @@ -97,10 +93,10 @@ pub fn map_stake_credential(cred: &PallasStakeCredential) -> StakeCredential {
pub fn map_stake_address(cred: &PallasStakeCredential, network_id: NetworkId) -> StakeAddress {
let payload = match cred {
PallasStakeCredential::AddrKeyhash(key_hash) => {
StakeAddressPayload::StakeKeyHash(key_hash.to_vec())
StakeCredential::AddrKeyHash(key_hash.to_vec())
}
PallasStakeCredential::ScriptHash(script_hash) => {
StakeAddressPayload::ScriptHash(script_hash.to_vec())
StakeCredential::ScriptHash(script_hash.to_vec())
}
};

Expand Down Expand Up @@ -265,7 +261,7 @@ pub fn map_certificate(
.iter()
.map(|v| {
StakeAddress::new(
StakeAddressPayload::StakeKeyHash(v.to_vec()),
StakeCredential::AddrKeyHash(v.to_vec()),
network_id.clone().into(),
)
})
Expand Down Expand Up @@ -375,7 +371,7 @@ pub fn map_certificate(
.into_iter()
.map(|v| {
StakeAddress::new(
StakeAddressPayload::StakeKeyHash(v.to_vec()),
StakeCredential::AddrKeyHash(v.to_vec()),
network_id.clone().into(),
)
})
Expand Down
121 changes: 53 additions & 68 deletions common/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@

use crate::cip19::{VarIntDecoder, VarIntEncoder};
use crate::types::{KeyHash, ScriptHash};
use crate::{Credential, NetworkId};
use crate::{Credential, NetworkId, StakeCredential};
use anyhow::{anyhow, bail, Result};
use crc::{Crc, CRC_32_ISO_HDLC};
use minicbor::data::IanaTag;
use serde_with::{hex::Hex, serde_as};
use std::cmp::Ordering;
use std::fmt::{Display, Formatter};

Expand Down Expand Up @@ -159,7 +158,7 @@ pub enum ShelleyAddressDelegationPart {
#[n(1)]
StakeKeyHash(#[n(0)] Vec<u8>),

/// Delegation to script key
/// Delegation to script key hash
#[n(2)]
ScriptHash(#[n(0)] ScriptHash),

Expand Down Expand Up @@ -357,55 +356,35 @@ impl ShelleyAddress {
}
}

/// Payload of a stake address
#[serde_as]
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash)]
pub enum StakeAddressPayload {
/// Stake key
StakeKeyHash(#[serde_as(as = "Hex")] KeyHash),

/// Script hash
ScriptHash(#[serde_as(as = "Hex")] ScriptHash),
}

impl StakeAddressPayload {
// Convert to string - note different encoding from when used as part of a StakeAddress
pub fn to_string(&self) -> Result<String> {
let (hrp, data) = match &self {
Self::StakeKeyHash(data) => (bech32::Hrp::parse("stake_vkh")?, data),
Self::ScriptHash(data) => (bech32::Hrp::parse("script")?, data),
};

Ok(bech32::encode::<bech32::Bech32>(hrp, data)?)
}
}

/// A stake address
#[derive(Debug, Clone, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)]
pub struct StakeAddress {
/// Network id
pub network: NetworkId,

/// Payload
pub payload: StakeAddressPayload,
/// Credential
pub credential: StakeCredential, // payload: StakePayload?
}

impl StakeAddress {
pub fn new(payload: StakeAddressPayload, network: NetworkId) -> Self {
StakeAddress { network, payload }
pub fn new(credential: StakeCredential, network: NetworkId) -> Self {
StakeAddress {
network,
credential,
}
}

pub fn get_hash(&self) -> &[u8] {
match &self.payload {
StakeAddressPayload::StakeKeyHash(hash) => hash,
StakeAddressPayload::ScriptHash(hash) => hash,
match &self.credential {
StakeCredential::AddrKeyHash(hash) => hash,
StakeCredential::ScriptHash(hash) => hash,
}
}

pub fn get_credential(&self) -> Credential {
match &self.payload {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This getter feels a bit silly now

StakeAddressPayload::StakeKeyHash(hash) => Credential::AddrKeyHash(hash.clone()),
StakeAddressPayload::ScriptHash(hash) => Credential::ScriptHash(hash.clone()),
match &self.credential {
StakeCredential::AddrKeyHash(hash) => Credential::AddrKeyHash(hash.clone()),
StakeCredential::ScriptHash(hash) => Credential::ScriptHash(hash.clone()),
}
}

Expand All @@ -429,13 +408,16 @@ impl StakeAddress {
false => NetworkId::Mainnet,
};

let payload = match (header >> 4) & 0x0Fu8 {
0b1110 => StakeAddressPayload::StakeKeyHash(data[1..].to_vec()),
0b1111 => StakeAddressPayload::ScriptHash(data[1..].to_vec()),
let credential = match (header >> 4) & 0x0Fu8 {
0b1110 => StakeCredential::AddrKeyHash(data[1..].to_vec()),
0b1111 => StakeCredential::ScriptHash(data[1..].to_vec()),
_ => return Err(anyhow!("Unknown header {header} in stake address")),
};

return Ok(StakeAddress { network, payload });
return Ok(StakeAddress {
network,
credential,
});
}

Err(anyhow!("Empty stake address data"))
Expand All @@ -448,9 +430,9 @@ impl StakeAddress {
NetworkId::Testnet => 0b0u8,
};

let (stake_bits, stake_hash): (u8, &Vec<u8>) = match &self.payload {
StakeAddressPayload::StakeKeyHash(data) => (0b1110, data),
StakeAddressPayload::ScriptHash(data) => (0b1111, data),
let (stake_bits, stake_hash): (u8, &Vec<u8>) = match &self.credential {
StakeCredential::AddrKeyHash(data) => (0b1110, data),
StakeCredential::ScriptHash(data) => (0b1111, data),
};

let mut data = vec![network_bits | (stake_bits << 4)];
Expand All @@ -469,20 +451,23 @@ impl StakeAddress {
_ => NetworkId::Testnet,
};

let payload = match (data[0] >> 4) & 0x0F {
0b1110 => StakeAddressPayload::StakeKeyHash(data[1..].to_vec()),
0b1111 => StakeAddressPayload::ScriptHash(data[1..].to_vec()),
let credential = match (data[0] >> 4) & 0x0F {
0b1110 => StakeCredential::AddrKeyHash(data[1..].to_vec()),
0b1111 => StakeCredential::ScriptHash(data[1..].to_vec()),
_ => bail!("Unknown header byte {:x} in stake address", data[0]),
};

Ok(StakeAddress { network, payload })
Ok(StakeAddress {
network,
credential,
})
}

pub fn to_bytes_key(&self) -> Result<Vec<u8>> {
let mut out = Vec::new();
let (bits, hash): (u8, &[u8]) = match &self.payload {
StakeAddressPayload::StakeKeyHash(h) => (0b1110, h),
StakeAddressPayload::ScriptHash(h) => (0b1111, h),
let (bits, hash): (u8, &[u8]) = match &self.credential {
StakeCredential::AddrKeyHash(h) => (0b1110, h),
StakeCredential::ScriptHash(h) => (0b1111, h),
};

let net_bit = match self.network {
Expand Down Expand Up @@ -529,7 +514,7 @@ impl Default for StakeAddress {
fn default() -> Self {
StakeAddress {
network: NetworkId::Mainnet,
payload: StakeAddressPayload::StakeKeyHash(vec![0u8; 28]),
credential: StakeCredential::AddrKeyHash(vec![0u8; 28]),
}
}
}
Expand Down Expand Up @@ -611,9 +596,9 @@ impl Address {
ShelleyAddressPaymentPart::PaymentKeyHash(_) => false,
ShelleyAddressPaymentPart::ScriptHash(_) => true,
},
Address::Stake(stake) => match stake.payload {
StakeAddressPayload::StakeKeyHash(_) => false,
StakeAddressPayload::ScriptHash(_) => true,
Address::Stake(stake) => match stake.credential {
StakeCredential::AddrKeyHash(_) => false,
StakeCredential::ScriptHash(_) => true,
},
Address::Byron(_) | Address::None => false,
}
Expand Down Expand Up @@ -828,7 +813,7 @@ mod tests {
fn shelley_type_14() {
let address = Address::Stake(StakeAddress {
network: NetworkId::Mainnet,
payload: StakeAddressPayload::StakeKeyHash(test_stake_key_hash()),
credential: StakeCredential::AddrKeyHash(test_stake_key_hash()),
});

let text = address.to_string().unwrap();
Expand All @@ -845,7 +830,7 @@ mod tests {
fn shelley_type_15() {
let address = Address::Stake(StakeAddress {
network: NetworkId::Mainnet,
payload: StakeAddressPayload::ScriptHash(test_script_hash()),
credential: StakeCredential::ScriptHash(test_script_hash()),
});

let text = address.to_string().unwrap();
Expand Down Expand Up @@ -890,8 +875,8 @@ mod tests {
let sa = StakeAddress::from_binary(&binary).unwrap();
assert_eq!(sa.network, NetworkId::Mainnet);
assert_eq!(
match sa.payload {
StakeAddressPayload::StakeKeyHash(key) => hex::encode(&key),
match sa.credential {
StakeCredential::AddrKeyHash(key) => hex::encode(&key),
_ => "SCRIPT".to_string(),
},
"558f3ee09b26d88fac2eddc772a9eda94cce6dbadbe9fee439bd6001"
Expand All @@ -906,8 +891,8 @@ mod tests {
let sa = StakeAddress::from_binary(&binary).unwrap();
assert_eq!(sa.network, NetworkId::Mainnet);
assert_eq!(
match sa.payload {
StakeAddressPayload::ScriptHash(key) => hex::encode(&key),
match sa.credential {
StakeCredential::ScriptHash(key) => hex::encode(&key),
_ => "STAKE".to_string(),
},
"558f3ee09b26d88fac2eddc772a9eda94cce6dbadbe9fee439bd6001"
Expand All @@ -922,8 +907,8 @@ mod tests {
let sa = StakeAddress::from_binary(&binary).unwrap();
assert_eq!(sa.network, NetworkId::Testnet);
assert_eq!(
match sa.payload {
StakeAddressPayload::StakeKeyHash(key) => hex::encode(&key),
match sa.credential {
StakeCredential::AddrKeyHash(key) => hex::encode(&key),
_ => "SCRIPT".to_string(),
},
"558f3ee09b26d88fac2eddc772a9eda94cce6dbadbe9fee439bd6001"
Expand Down Expand Up @@ -975,8 +960,8 @@ mod tests {

assert_eq!(decoded.network, NetworkId::Mainnet);
assert_eq!(
match decoded.payload {
StakeAddressPayload::StakeKeyHash(key) => hex::encode(&key),
match decoded.credential {
StakeCredential::AddrKeyHash(key) => hex::encode(&key),
_ => "STAKE".to_string(),
},
"558f3ee09b26d88fac2eddc772a9eda94cce6dbadbe9fee439bd6001"
Expand All @@ -998,8 +983,8 @@ mod tests {

assert_eq!(decoded.network, NetworkId::Mainnet);
assert_eq!(
match decoded.payload {
StakeAddressPayload::ScriptHash(key) => hex::encode(&key),
match decoded.credential {
StakeCredential::ScriptHash(key) => hex::encode(&key),
_ => "STAKE".to_string(),
},
"558f3ee09b26d88fac2eddc772a9eda94cce6dbadbe9fee439bd6001"
Expand All @@ -1019,8 +1004,8 @@ mod tests {

assert_eq!(decoded.network, NetworkId::Testnet);
assert_eq!(
match decoded.payload {
StakeAddressPayload::ScriptHash(key) => hex::encode(&key),
match decoded.credential {
StakeCredential::ScriptHash(key) => hex::encode(&key),
_ => "SCRIPT".to_string(),
},
"558f3ee09b26d88fac2eddc772a9eda94cce6dbadbe9fee439bd6001"
Expand Down
6 changes: 2 additions & 4 deletions common/src/stake_addresses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ impl StakeAddressMap {

#[cfg(test)]
mod tests {
use crate::{NetworkId, StakeAddress, StakeAddressPayload};
use crate::{NetworkId, StakeAddress, StakeCredential};

use super::*;

Expand All @@ -558,9 +558,7 @@ mod tests {

fn create_stake_address(hash: &[u8]) -> StakeAddress {
StakeAddress::new(
StakeAddressPayload::StakeKeyHash(
hash.to_vec().try_into().expect("Invalid hash length"),
),
StakeCredential::AddrKeyHash(hash.to_vec().try_into().expect("Invalid hash length")),
NetworkId::Mainnet,
)
}
Expand Down
16 changes: 14 additions & 2 deletions common/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,15 +625,16 @@ pub struct PotDelta {
pub delta: LovelaceDelta,
}

#[serde_as]
#[derive(
Debug, Clone, Ord, Eq, PartialEq, PartialOrd, Hash, serde::Serialize, serde::Deserialize,
)]
pub enum Credential {
/// Script hash. NOTE: Order matters when parsing Haskell Node Snapshot data.
ScriptHash(KeyHash),
ScriptHash(#[serde_as(as = "Hex")] KeyHash),

/// Address key hash
AddrKeyHash(KeyHash),
AddrKeyHash(#[serde_as(as = "Hex")] KeyHash),
}

impl Credential {
Expand Down Expand Up @@ -735,6 +736,17 @@ impl Credential {

pub type StakeCredential = Credential;

impl StakeCredential {
pub fn to_string(&self) -> Result<String> {
let (hrp, data) = match &self {
Self::AddrKeyHash(data) => (Hrp::parse("stake_vkh")?, data),
Self::ScriptHash(data) => (Hrp::parse("script")?, data),
};

Ok(bech32::encode::<Bech32>(hrp, data)?)
}
}

/// Relay single host address
#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq)]
pub struct SingleHostAddr {
Expand Down
6 changes: 2 additions & 4 deletions modules/accounts_state/src/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,17 +187,15 @@ mod tests {
use super::*;
use acropolis_common::stake_addresses::StakeAddressState;
use acropolis_common::NetworkId::Mainnet;
use acropolis_common::{StakeAddress, StakeAddressPayload};
use acropolis_common::{StakeAddress, StakeCredential};

// Helper function to create stake addresses for testing
fn create_test_stake_address(id: u8) -> StakeAddress {
let mut hash = vec![0u8; 28];
hash[0] = id;
StakeAddress {
network: Mainnet,
payload: StakeAddressPayload::StakeKeyHash(
hash.try_into().expect("Invalid hash length"),
),
credential: StakeCredential::AddrKeyHash(hash.try_into().expect("Invalid hash length")),
}
}

Expand Down
Loading