Skip to content

Commit 7e6f4bd

Browse files
authored
Merge pull request #367 from Emurgo/ptr-addr-u64
PointerAddress support for >u32::MAX
2 parents 4f1d875 + 2158fe8 commit 7e6f4bd

File tree

2 files changed

+47
-29
lines changed

2 files changed

+47
-29
lines changed

rust/src/address.rs

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ use ed25519_bip32::XPub;
66
// returns (Number represented, bytes read) if valid encoding
77
// or None if decoding prematurely finished
88
fn variable_nat_decode(bytes: &[u8]) -> Option<(u64, usize)> {
9-
let mut output = 0u64;
9+
let mut output = 0u128;
1010
let mut bytes_read = 0;
1111
for byte in bytes {
12-
output = (output << 7) | (byte & 0x7F) as u64;
12+
output = (output << 7) | (byte & 0x7F) as u128;
13+
if output > u64::MAX.into() {
14+
return None;
15+
}
1316
bytes_read += 1;
1417
if (byte & 0x80) == 0 {
15-
return Some((output, bytes_read));
18+
return Some((output as u64, bytes_read));
1619
}
1720
}
1821
None
@@ -293,9 +296,9 @@ impl Address {
293296
| (ptr.network & 0xF);
294297
buf.push(header);
295298
buf.extend(ptr.payment.to_raw_bytes());
296-
buf.extend(variable_nat_encode(ptr.stake.slot.into()));
297-
buf.extend(variable_nat_encode(ptr.stake.tx_index.into()));
298-
buf.extend(variable_nat_encode(ptr.stake.cert_index.into()));
299+
buf.extend(variable_nat_encode(from_bignum(&ptr.stake.slot)));
300+
buf.extend(variable_nat_encode(from_bignum(&ptr.stake.tx_index)));
301+
buf.extend(variable_nat_encode(from_bignum(&ptr.stake.cert_index)));
299302
},
300303
AddrType::Enterprise(enterprise) => {
301304
let header: u8 = 0b0110_0000
@@ -393,9 +396,9 @@ impl Address {
393396
network,
394397
&payment_cred,
395398
&Pointer::new(
396-
slot.try_into().map_err(|_| DeserializeError::new("Address.Pointer.slot", DeserializeFailure::CBOR(cbor_event::Error::ExpectedU32)))?,
397-
tx_index.try_into().map_err(|_| DeserializeError::new("Address.Pointer.tx_index", DeserializeFailure::CBOR(cbor_event::Error::ExpectedU32)))?,
398-
cert_index.try_into().map_err(|_| DeserializeError::new("Address.Pointer.cert_index", DeserializeFailure::CBOR(cbor_event::Error::ExpectedU32)))?)))
399+
&to_bignum(slot),
400+
&to_bignum(tx_index),
401+
&to_bignum(cert_index))))
399402
},
400403
// enterprise
401404
0b0110 | 0b0111 => {
@@ -608,30 +611,30 @@ impl Deserialize for RewardAddress {
608611
#[wasm_bindgen]
609612
#[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)]
610613
pub struct Pointer {
611-
slot: Slot,
612-
tx_index: TransactionIndex,
613-
cert_index: CertificateIndex,
614+
slot: BigNum,
615+
tx_index: BigNum,
616+
cert_index: BigNum,
614617
}
615618

616619
#[wasm_bindgen]
617620
impl Pointer {
618-
pub fn new(slot: Slot, tx_index: TransactionIndex, cert_index: CertificateIndex) -> Self {
621+
pub fn new(slot: &BigNum, tx_index: &BigNum, cert_index: &BigNum) -> Self {
619622
Self {
620-
slot,
621-
tx_index,
622-
cert_index,
623+
slot: slot.clone(),
624+
tx_index: tx_index.clone(),
625+
cert_index: cert_index.clone(),
623626
}
624627
}
625628

626-
pub fn slot(&self) -> Slot {
629+
pub fn slot(&self) -> BigNum {
627630
self.slot.clone()
628631
}
629632

630-
pub fn tx_index(&self) -> TransactionIndex {
633+
pub fn tx_index(&self) -> BigNum {
631634
self.tx_index.clone()
632635
}
633636

634-
pub fn cert_index(&self) -> CertificateIndex {
637+
pub fn cert_index(&self) -> BigNum {
635638
self.cert_index.clone()
636639
}
637640
}
@@ -695,6 +698,12 @@ mod tests {
695698
}
696699
}
697700

701+
#[test]
702+
fn variable_nat_decode_too_big() {
703+
let too_big = [129, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127];
704+
assert_eq!(None, variable_nat_decode(&too_big));
705+
}
706+
698707
#[test]
699708
fn base_serialize_consistency() {
700709
let base = BaseAddress::new(
@@ -711,7 +720,7 @@ mod tests {
711720
let ptr = PointerAddress::new(
712721
25,
713722
&StakeCredential::from_keyhash(&Ed25519KeyHash::from([23; Ed25519KeyHash::BYTE_COUNT])),
714-
&Pointer::new(2354556573, 127, 0));
723+
&Pointer::new(&to_bignum(2354556573), &to_bignum(127), &to_bignum(0)));
715724
let addr = ptr.to_address();
716725
let addr2 = Address::from_bytes(addr.to_bytes()).unwrap();
717726
assert_eq!(addr.to_bytes(), addr2.to_bytes());
@@ -827,9 +836,9 @@ mod tests {
827836
.derive(0)
828837
.to_public();
829838
let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash());
830-
let addr_net_0 = PointerAddress::new(NetworkInfo::testnet().network_id(), &spend_cred, &Pointer::new(1, 2, 3)).to_address();
839+
let addr_net_0 = PointerAddress::new(NetworkInfo::testnet().network_id(), &spend_cred, &Pointer::new(&to_bignum(1), &to_bignum(2), &to_bignum(3))).to_address();
831840
assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1gz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzerspqgpsqe70et");
832-
let addr_net_3 = PointerAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred, &Pointer::new(24157, 177, 42)).to_address();
841+
let addr_net_3 = PointerAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred, &Pointer::new(&to_bignum(24157), &to_bignum(177), &to_bignum(42))).to_address();
833842
assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1gx2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer5ph3wczvf2w8lunk");
834843
}
835844

@@ -883,9 +892,9 @@ mod tests {
883892
.derive(0)
884893
.to_public();
885894
let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash());
886-
let addr_net_0 = PointerAddress::new(NetworkInfo::testnet().network_id(), &spend_cred, &Pointer::new(1, 2, 3)).to_address();
895+
let addr_net_0 = PointerAddress::new(NetworkInfo::testnet().network_id(), &spend_cred, &Pointer::new(&to_bignum(1), &to_bignum(2), &to_bignum(3))).to_address();
887896
assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1gpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5egpqgpsdhdyc0");
888-
let addr_net_3 = PointerAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred, &Pointer::new(24157, 177, 42)).to_address();
897+
let addr_net_3 = PointerAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred, &Pointer::new(&to_bignum(24157), &to_bignum(177), &to_bignum(42))).to_address();
889898
assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1g9u5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5evph3wczvf2kd5vam");
890899
}
891900

@@ -966,9 +975,9 @@ mod tests {
966975
.derive(0)
967976
.to_public();
968977
let spend_cred = StakeCredential::from_keyhash(&spend.to_raw_key().hash());
969-
let addr_net_0 = PointerAddress::new(NetworkInfo::testnet().network_id(), &spend_cred, &Pointer::new(1, 2, 3)).to_address();
978+
let addr_net_0 = PointerAddress::new(NetworkInfo::testnet().network_id(), &spend_cred, &Pointer::new(&to_bignum(1), &to_bignum(2), &to_bignum(3))).to_address();
970979
assert_eq!(addr_net_0.to_bech32(None).unwrap(), "addr_test1gqy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnqpqgps5mee0p");
971-
let addr_net_3 = PointerAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred, &Pointer::new(24157, 177, 42)).to_address();
980+
let addr_net_3 = PointerAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred, &Pointer::new(&to_bignum(24157), &to_bignum(177), &to_bignum(42))).to_address();
972981
assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1gyy6nhfyks7wdu3dudslys37v252w2nwhv0fw2nfawemmnyph3wczvf2dqflgt");
973982
}
974983

@@ -1041,4 +1050,13 @@ mod tests {
10411050
let addr_net_3 = BaseAddress::new(NetworkInfo::mainnet().network_id(), &spend_cred, &stake_cred).to_address();
10421051
assert_eq!(addr_net_3.to_bech32(None).unwrap(), "addr1x80de0mz3m9xmgtlmqqzu06s0uvfsczskdec8k7v4jhr7077mjlk9rk2dkshlkqq9cl4qlccnps9pvmns0duet9w8ulsylzv28");
10431052
}
1053+
1054+
#[test]
1055+
fn pointer_address_big() {
1056+
let addr = Address::from_bech32("addr_test1grqe6lg9ay8wkcu5k5e38lne63c80h3nq6xxhqfmhewf645pllllllllllll7lupllllllllllll7lupllllllllllll7lc9wayvj").unwrap();
1057+
let ptr = PointerAddress::from_address(&addr).unwrap().stake;
1058+
assert_eq!(u64::MAX, from_bignum(&ptr.slot));
1059+
assert_eq!(u64::MAX, from_bignum(&ptr.tx_index));
1060+
assert_eq!(u64::MAX, from_bignum(&ptr.cert_index));
1061+
}
10441062
}

rust/src/tx_builder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,9 +1847,9 @@ mod tests {
18471847
NetworkInfo::testnet().network_id(),
18481848
&spend_cred,
18491849
&Pointer::new(
1850-
0,
1851-
0,
1852-
0
1850+
&to_bignum(0),
1851+
&to_bignum(0),
1852+
&to_bignum(0)
18531853
)
18541854
).to_address(),
18551855
&TransactionInput::new(&genesis_id(), 0),

0 commit comments

Comments
 (0)