Skip to content
This repository has been archived by the owner on May 4, 2024. It is now read-only.

Commit

Permalink
[account-address] Make display and hex outputs consistent
Browse files Browse the repository at this point in the history
  • Loading branch information
gregnazario committed Apr 19, 2022
1 parent 1817aff commit 4684dca
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 45 deletions.
2 changes: 1 addition & 1 deletion language/evm/move-to-yul/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ impl Generator {
emit!(ctx.writer, "let $arg{} := ", idx);
match arg {
MoveValue::Address(addr) => {
emitln!(ctx.writer, "{}", addr.to_hex_literal());
emitln!(ctx.writer, "{}", addr);
}
_ => unreachable!(
"only address literals are allowed as test arguments currently"
Expand Down
47 changes: 27 additions & 20 deletions language/move-core/types/src/account_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ impl AccountAddress {
Self(buf)
}

/// A shortened version with leading 0s are stripped from the hex
pub fn short_str_lossless(&self) -> String {
let hex_str = hex::encode(&self.0).trim_start_matches('0').to_string();
let hex_str = hex::encode_upper(&self.0)
.trim_start_matches('0')
.to_string();
if hex_str.is_empty() {
"0".to_string()
} else {
Expand All @@ -61,6 +64,17 @@ impl AccountAddress {
self.0
}

/// Reads hex that starts with a 0x or doesn't start with a 0x
pub fn from_hex_fuzzy(literal: &str) -> Result<Self, AccountAddressParseError> {
if literal.starts_with("0x") {
Self::from_hex_literal(literal)
} else {
Self::from_hex(literal)
}
}

/// Reads a hex literal 0xABCD, and requires a 0x in front, but not
/// necessarily [`Self::LENGTH`] in length
pub fn from_hex_literal(literal: &str) -> Result<Self, AccountAddressParseError> {
if !literal.starts_with("0x") {
return Err(AccountAddressParseError);
Expand All @@ -81,20 +95,13 @@ impl AccountAddress {
}
}

pub fn to_hex_literal(&self) -> String {
format!("0x{}", self.short_str_lossless())
}

/// Reads hex that must be exactly [`Self::LENGTH`] length
pub fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, AccountAddressParseError> {
<[u8; Self::LENGTH]>::from_hex(hex)
.map_err(|_| AccountAddressParseError)
.map(Self)
}

pub fn to_hex(&self) -> String {
self.short_str_lossless()
}

pub fn from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, AccountAddressParseError> {
<[u8; Self::LENGTH]>::try_from(bytes.as_ref())
.map_err(|_| AccountAddressParseError)
Expand All @@ -118,13 +125,13 @@ impl std::ops::Deref for AccountAddress {

impl fmt::Display for AccountAddress {
fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
write!(f, "{:X}", self)
write!(f, "{:#X}", self)
}
}

impl fmt::Debug for AccountAddress {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:X}", self)
write!(f, "{:#X}", self)
}
}

Expand Down Expand Up @@ -206,7 +213,7 @@ impl From<&AccountAddress> for [u8; AccountAddress::LENGTH] {

impl From<&AccountAddress> for String {
fn from(addr: &AccountAddress) -> String {
addr.to_hex_literal()
addr.to_string()
}
}

Expand All @@ -222,7 +229,7 @@ impl FromStr for AccountAddress {
type Err = AccountAddressParseError;

fn from_str(s: &str) -> Result<Self, AccountAddressParseError> {
Self::from_hex_literal(s)
Self::from_hex_fuzzy(s)
}
}

Expand All @@ -233,7 +240,7 @@ impl<'de> Deserialize<'de> for AccountAddress {
{
if deserializer.is_human_readable() {
let s = <String>::deserialize(deserializer)?;
AccountAddress::from_hex_literal(&s).map_err(D::Error::custom)
AccountAddress::from_hex_fuzzy(&s).map_err(D::Error::custom)
} else {
// In order to preserve the Serde data model and help analysis tools,
// make sure to wrap our value in a container with the same name
Expand All @@ -254,7 +261,7 @@ impl Serialize for AccountAddress {
S: Serializer,
{
if serializer.is_human_readable() {
self.to_hex_literal().serialize(serializer)
self.to_string().serialize(serializer)
} else {
// See comment in deserialize.
serializer.serialize_newtype_struct("AccountAddress", &self.0)
Expand Down Expand Up @@ -290,8 +297,8 @@ mod tests {

let address = AccountAddress::from_hex(hex).unwrap();

assert_eq!(format!("{}", address), upper_hex);
assert_eq!(format!("{:?}", address), upper_hex);
assert_eq!(format!("{}", address), format!("0x{}", upper_hex));
assert_eq!(format!("{:?}", address), format!("0x{}", upper_hex));
assert_eq!(format!("{:X}", address), upper_hex);
assert_eq!(format!("{:x}", address), hex);

Expand All @@ -305,7 +312,7 @@ mod tests {

assert_eq!(
address.short_str_lossless(),
"c0f1f95c5b1c5f0eda533eff269000",
"C0F1F95C5B1C5F0EDA533EFF269000",
);
}

Expand Down Expand Up @@ -337,14 +344,14 @@ mod tests {

#[test]
fn test_from_hex_literal() {
let hex_literal = "0x1";
let hex_literal = "0x00000000000000000000000000000001";
let hex = "00000000000000000000000000000001";

let address_from_literal = AccountAddress::from_hex_literal(hex_literal).unwrap();
let address = AccountAddress::from_hex(hex).unwrap();

assert_eq!(address_from_literal, address);
assert_eq!(hex_literal, address.to_hex_literal());
assert_eq!(hex_literal, address.to_string());

// Check other variations of 0x1
assert_eq!(AccountAddress::from_str("0x01").unwrap(), address);
Expand Down
14 changes: 1 addition & 13 deletions language/testing-infra/transactional-test-runner/src/tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,9 @@ pub enum RawAddress {
Anonymous(AccountAddress),
}

fn parse_address_literal(s: &str) -> Result<AccountAddress> {
let (array, _) = move_compiler::shared::parse_address(s).ok_or_else(|| {
anyhow!(
"Failed to parse address {} to AccountAddress with Length {}",
s,
AccountAddress::LENGTH
)
})?;

Ok(AccountAddress::new(array))
}

impl RawAddress {
pub fn parse(s: &str) -> Result<Self> {
if let Ok(addr) = parse_address_literal(s) {
if let Ok(addr) = AccountAddress::from_hex_fuzzy(s) {
return Ok(Self::Anonymous(addr));
}
let name =
Expand Down
18 changes: 7 additions & 11 deletions language/tools/move-package/src/source_package/manifest_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use crate::{source_package::parsed_manifest as PM, Architecture};
use anyhow::{bail, format_err, Context, Result};
use move_core_types::account_address::{AccountAddress, AccountAddressParseError};
use move_core_types::account_address::AccountAddress;
use move_symbol_pool::symbol::Symbol;
use std::{
collections::{BTreeMap, BTreeSet},
Expand Down Expand Up @@ -213,7 +213,10 @@ pub fn parse_addresses(tval: TV) -> Result<PM::AddressDeclarations> {
} else if addresses
.insert(
ident,
Some(parse_address_literal(entry_str).context("Invalid address")?),
Some(
AccountAddress::from_hex_fuzzy(entry_str)
.context("Invalid address")?,
),
)
.is_some()
{
Expand Down Expand Up @@ -251,7 +254,8 @@ pub fn parse_dev_addresses(tval: TV) -> Result<PM::DevAddressDeclarations> {
} else if addresses
.insert(
ident,
parse_address_literal(entry_str).context("Invalid address")?,
AccountAddress::from_hex_fuzzy(entry_str)
.context("Invalid address")?,
)
.is_some()
{
Expand All @@ -275,14 +279,6 @@ pub fn parse_dev_addresses(tval: TV) -> Result<PM::DevAddressDeclarations> {
}
}

// Safely parses address for both the 0x and non prefixed hex format.
fn parse_address_literal(address_str: &str) -> Result<AccountAddress, AccountAddressParseError> {
if !address_str.starts_with("0x") {
return AccountAddress::from_hex(address_str);
}
AccountAddress::from_hex_literal(address_str)
}

fn parse_dependency(tval: TV) -> Result<PM::Dependency> {
match tval {
TV::Table(mut table) => {
Expand Down

0 comments on commit 4684dca

Please sign in to comment.