Skip to content

Commit 10c2c09

Browse files
committed
fix: Shelley to/from_bytes_key header byte encoding
Signed-off-by: William Hankins <[email protected]>
1 parent 084ed31 commit 10c2c09

File tree

1 file changed

+74
-22
lines changed

1 file changed

+74
-22
lines changed

common/src/address.rs

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,10 @@ impl ShelleyAddress {
308308

309309
let mut data = Vec::new();
310310

311-
let build_header =
312-
|variant: u8| -> u8 { network_bits | (payment_bits << 4) | (variant << 5) };
311+
let build_header = |delegation_bits: u8| -> u8 {
312+
let addr_type = ((delegation_bits & 0x03) << 1) | (payment_bits & 0x01);
313+
(addr_type << 4) | (network_bits & 0x0F)
314+
};
313315

314316
match &self.delegation {
315317
ShelleyAddressDelegationPart::None => {
@@ -357,8 +359,10 @@ impl ShelleyAddress {
357359
_ => return Err(anyhow!("invalid network bits in header")),
358360
};
359361

360-
let payment_bits = (header >> 4) & 0x01;
361-
let delegation_bits = (header >> 5) & 0x03;
362+
let addr_type = (header >> 4) & 0x0F;
363+
364+
let payment_bits = addr_type & 0x01;
365+
let delegation_bits = (addr_type >> 1) & 0x03;
362366

363367
let payment_hash = {
364368
let mut arr = [0u8; 28];
@@ -1117,49 +1121,97 @@ mod tests {
11171121
let stake_hash = Hash::new([0x22; 28]);
11181122
let script_hash = Hash::new([0x33; 28]);
11191123

1120-
// Normal address
1121-
let addr_base = ShelleyAddress {
1124+
// (KeyHash, StakeKeyHash)
1125+
let type_1 = ShelleyAddress {
11221126
network: NetworkId::Mainnet,
11231127
payment: ShelleyAddressPaymentPart::PaymentKeyHash(payment_hash),
11241128
delegation: ShelleyAddressDelegationPart::StakeKeyHash(stake_hash),
11251129
};
1126-
let bytes = addr_base.to_bytes_key();
1130+
let bytes = type_1.to_bytes_key();
1131+
assert_eq!(bytes[0], 0x01);
1132+
let decoded = ShelleyAddress::from_bytes_key(&bytes).expect("decode base");
1133+
assert_eq!(type_1, decoded);
1134+
1135+
// (ScriptKeyHash, StakeKeyHash)
1136+
let type_2 = ShelleyAddress {
1137+
network: NetworkId::Mainnet,
1138+
payment: ShelleyAddressPaymentPart::ScriptHash(payment_hash),
1139+
delegation: ShelleyAddressDelegationPart::StakeKeyHash(stake_hash),
1140+
};
1141+
let bytes = type_2.to_bytes_key();
1142+
assert_eq!(bytes[0], 0x11);
1143+
let decoded = ShelleyAddress::from_bytes_key(&bytes).expect("decode base");
1144+
assert_eq!(type_2, decoded);
1145+
1146+
// (KeyHash, ScriptHash)
1147+
let type_3 = ShelleyAddress {
1148+
network: NetworkId::Mainnet,
1149+
payment: ShelleyAddressPaymentPart::PaymentKeyHash(payment_hash),
1150+
delegation: ShelleyAddressDelegationPart::ScriptHash(stake_hash),
1151+
};
1152+
let bytes = type_3.to_bytes_key();
1153+
assert_eq!(bytes[0], 0x21);
11271154
let decoded = ShelleyAddress::from_bytes_key(&bytes).expect("decode base");
1128-
assert_eq!(addr_base, decoded);
1155+
assert_eq!(type_3, decoded);
11291156

1130-
// Script address
1131-
let addr_script = ShelleyAddress {
1132-
network: NetworkId::Testnet,
1157+
// (ScriptHash, ScriptHash)
1158+
let type_4 = ShelleyAddress {
1159+
network: NetworkId::Mainnet,
11331160
payment: ShelleyAddressPaymentPart::ScriptHash(payment_hash),
11341161
delegation: ShelleyAddressDelegationPart::ScriptHash(script_hash),
11351162
};
1136-
let bytes = addr_script.to_bytes_key();
1163+
let bytes = type_4.to_bytes_key();
1164+
assert_eq!(bytes[0], 0x31);
11371165
let decoded = ShelleyAddress::from_bytes_key(&bytes).expect("decode script");
1138-
assert_eq!(addr_script, decoded);
1166+
assert_eq!(type_4, decoded);
11391167

1140-
// Pointer address
1168+
// (KeyHash, Pointer)
11411169
let pointer = ShelleyAddressPointer {
11421170
slot: 1234,
11431171
tx_index: 56,
11441172
cert_index: 2,
11451173
};
1146-
let addr_pointer = ShelleyAddress {
1174+
let type_5 = ShelleyAddress {
11471175
network: NetworkId::Mainnet,
11481176
payment: ShelleyAddressPaymentPart::PaymentKeyHash(payment_hash),
1177+
delegation: ShelleyAddressDelegationPart::Pointer(pointer.clone()),
1178+
};
1179+
let bytes = type_5.to_bytes_key();
1180+
assert_eq!(bytes[0], 0x41);
1181+
let decoded = ShelleyAddress::from_bytes_key(&bytes).expect("decode pointer");
1182+
assert_eq!(type_5, decoded);
1183+
1184+
// (ScriptHash, Pointer)
1185+
let type_6 = ShelleyAddress {
1186+
network: NetworkId::Mainnet,
1187+
payment: ShelleyAddressPaymentPart::ScriptHash(payment_hash),
11491188
delegation: ShelleyAddressDelegationPart::Pointer(pointer),
11501189
};
1151-
let bytes = addr_pointer.to_bytes_key();
1190+
let bytes = type_6.to_bytes_key();
1191+
assert_eq!(bytes[0], 0x51);
11521192
let decoded = ShelleyAddress::from_bytes_key(&bytes).expect("decode pointer");
1153-
assert_eq!(addr_pointer, decoded);
1193+
assert_eq!(type_6, decoded);
11541194

1155-
// Enterprise address
1156-
let addr_none = ShelleyAddress {
1157-
network: NetworkId::Testnet,
1195+
// (KeyHash, None)
1196+
let type_7 = ShelleyAddress {
1197+
network: NetworkId::Mainnet,
11581198
payment: ShelleyAddressPaymentPart::PaymentKeyHash(payment_hash),
11591199
delegation: ShelleyAddressDelegationPart::None,
11601200
};
1161-
let bytes = addr_none.to_bytes_key();
1201+
let bytes = type_7.to_bytes_key();
1202+
assert_eq!(bytes[0], 0x61);
1203+
let decoded = ShelleyAddress::from_bytes_key(&bytes).expect("decode none");
1204+
assert_eq!(type_7, decoded);
1205+
1206+
// (ScriptHash, None)
1207+
let type_8 = ShelleyAddress {
1208+
network: NetworkId::Mainnet,
1209+
payment: ShelleyAddressPaymentPart::ScriptHash(payment_hash),
1210+
delegation: ShelleyAddressDelegationPart::None,
1211+
};
1212+
let bytes = type_8.to_bytes_key();
1213+
assert_eq!(bytes[0], 0x71);
11621214
let decoded = ShelleyAddress::from_bytes_key(&bytes).expect("decode none");
1163-
assert_eq!(addr_none, decoded);
1215+
assert_eq!(type_8, decoded);
11641216
}
11651217
}

0 commit comments

Comments
 (0)