Skip to content

Commit 14e5d92

Browse files
lxfindbors-libra
authored andcommitted
Support 20 bytes address
Closes: #10
1 parent d253bf1 commit 14e5d92

File tree

9 files changed

+63
-27
lines changed

9 files changed

+63
-27
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

language/move-compiler/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ petgraph = "0.5.1"
1717
walkdir = "2.3.1"
1818
tempfile = "3.2.0"
1919
once_cell = "1.7.2"
20+
num-bigint = "0.4.0"
2021

2122
move-binary-format = { path = "../move-binary-format" }
2223
move-core-types = { path = "../move-core/types" }

language/move-compiler/src/shared/mod.rs

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::{
88
use move_core_types::account_address::AccountAddress;
99
use move_ir_types::location::*;
1010
use move_symbol_pool::Symbol;
11+
use num_bigint::BigUint;
1112
use petgraph::{algo::astar as petgraph_astar, graphmap::DiGraphMap};
1213
use std::{
1314
collections::BTreeMap,
@@ -61,6 +62,25 @@ pub fn parse_u128(s: &str) -> Result<(u128, NumberFormat), ParseIntError> {
6162
Ok((u128::from_str_radix(txt, base as u32)?, base))
6263
}
6364

65+
// Parse an address from a decimal or hex encoding
66+
pub fn parse_address(s: &str) -> Option<([u8; AccountAddress::LENGTH], NumberFormat)> {
67+
let (txt, base) = determine_num_text_and_base(s);
68+
let parsed = BigUint::parse_bytes(
69+
txt.as_bytes(),
70+
match base {
71+
NumberFormat::Hex => 16,
72+
NumberFormat::Decimal => 10,
73+
},
74+
)?;
75+
let bytes = parsed.to_bytes_be();
76+
if bytes.len() > AccountAddress::LENGTH {
77+
return None;
78+
}
79+
let mut result = [0u8; AccountAddress::LENGTH];
80+
result[(AccountAddress::LENGTH - bytes.len())..].clone_from_slice(&bytes);
81+
Some((result, base))
82+
}
83+
6484
//**************************************************************************************************
6585
// Address
6686
//**************************************************************************************************
@@ -78,9 +98,7 @@ pub struct NumericalAddress {
7898
impl NumericalAddress {
7999
// bytes used for errors when an address is not known but is needed
80100
pub const DEFAULT_ERROR_ADDRESS: Self = NumericalAddress {
81-
bytes: AccountAddress::new([
82-
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
83-
]),
101+
bytes: AccountAddress::ONE,
84102
format: NumberFormat::Hex,
85103
};
86104

@@ -100,22 +118,22 @@ impl NumericalAddress {
100118
}
101119

102120
pub fn parse_str(s: &str) -> Result<NumericalAddress, String> {
103-
let (n, format) = match parse_u128(s) {
104-
Ok(res) => res,
105-
Err(_) => {
106-
// TODO the kind of error is in an unstable nightly API
107-
// But currently the only way this should fail is if the number is too long
108-
return Err(
121+
match parse_address(s) {
122+
Some((n, format)) => Ok(NumericalAddress {
123+
bytes: AccountAddress::new(n),
124+
format,
125+
}),
126+
None =>
127+
// TODO the kind of error is in an unstable nightly API
128+
// But currently the only way this should fail is if the number is too long
129+
{
130+
Err(format!(
109131
"Invalid address literal. The numeric value is too large. The maximum size is \
110-
16 bytes"
111-
.to_owned(),
112-
);
132+
{} bytes",
133+
AccountAddress::LENGTH
134+
))
113135
}
114-
};
115-
Ok(NumericalAddress {
116-
bytes: AccountAddress::new(n.to_be_bytes()),
117-
format,
118-
})
136+
}
119137
}
120138
}
121139

@@ -129,7 +147,7 @@ impl fmt::Display for NumericalAddress {
129147
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
130148
match self.format {
131149
NumberFormat::Decimal => {
132-
let n = u128::from_be_bytes(self.bytes.into_bytes());
150+
let n = BigUint::from_bytes_be(self.bytes.as_ref());
133151
write!(f, "{}", n)
134152
}
135153
NumberFormat::Hex => write!(f, "{:#X}", self),

language/move-core/types/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ regex = "1.4.3"
3030
serde_json = "1.0.64"
3131

3232
[features]
33+
address20 = []
3334
default = []
3435
fuzzing = ["proptest", "proptest-derive"]

language/move-core/types/src/account_address.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,21 @@ impl AccountAddress {
1717
}
1818

1919
/// The number of bytes in an address.
20-
pub const LENGTH: usize = 16;
20+
/// Default to 16 bytes, can be set to 20 bytes with address20 feature.
21+
pub const LENGTH: usize = if cfg!(feature = "address20") { 20 } else { 16 };
2122

2223
/// Hex address: 0x0
2324
pub const ZERO: Self = Self([0u8; Self::LENGTH]);
2425

26+
/// Hex address: 0x1
27+
pub const ONE: Self = Self::get_hex_address_one();
28+
29+
const fn get_hex_address_one() -> Self {
30+
let mut addr = [0u8; AccountAddress::LENGTH];
31+
addr[AccountAddress::LENGTH - 1] = 1u8;
32+
Self(addr)
33+
}
34+
2535
pub fn random() -> Self {
2636
let mut rng = OsRng;
2737
let buf: [u8; Self::LENGTH] = rng.gen();

language/move-core/types/src/language_storage.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ use std::fmt::{Display, Formatter};
1313
pub const CODE_TAG: u8 = 0;
1414
pub const RESOURCE_TAG: u8 = 1;
1515

16-
pub const CORE_CODE_ADDRESS: AccountAddress = AccountAddress::new([
17-
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
18-
]);
16+
/// Hex address: 0x1
17+
pub const CORE_CODE_ADDRESS: AccountAddress = AccountAddress::ONE;
1918

2019
#[derive(Serialize, Deserialize, Debug, PartialEq, Hash, Eq, Clone, PartialOrd, Ord)]
2120
pub enum TypeTag {

language/move-prover/interpreter/src/concrete/evaluator.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ pub type EvalResult<T> = ::std::result::Result<T, BigInt>;
4141
// Constants
4242
//**************************************************************************************************
4343

44-
const DIEM_CORE_ADDR: AccountAddress =
45-
AccountAddress::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
44+
const DIEM_CORE_ADDR: AccountAddress = AccountAddress::ONE;
4645

4746
//**************************************************************************************************
4847
// Evaluation context

language/move-prover/interpreter/src/concrete/player.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use bytecode_interpreter_crypto::{
1313
use move_binary_format::errors::Location;
1414
use move_core_types::{
1515
account_address::AccountAddress,
16+
language_storage::CORE_CODE_ADDRESS,
1617
vm_status::{sub_status, StatusCode},
1718
};
1819
use move_model::{
@@ -53,8 +54,7 @@ pub type ExecResult<T> = ::std::result::Result<T, AbortInfo>;
5354
// Constants
5455
//**************************************************************************************************
5556

56-
const DIEM_CORE_ADDR: AccountAddress =
57-
AccountAddress::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
57+
const DIEM_CORE_ADDR: AccountAddress = CORE_CODE_ADDRESS;
5858

5959
// TODO(mengxu): these constants are defined in values_impl.rs which are currently not exposed.
6060
const INDEX_OUT_OF_BOUNDS: u64 = sub_status::NFE_VECTOR_ERROR_BASE + 1;

language/move-stdlib/src/natives/unit_test.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ use std::collections::VecDeque;
1212

1313
use move_core_types::account_address::AccountAddress;
1414

15+
fn to_le_bytes(i: u64) -> [u8; AccountAddress::LENGTH] {
16+
let bytes = i.to_le_bytes();
17+
let mut result = [0u8; AccountAddress::LENGTH];
18+
result[..bytes.len()].clone_from_slice(bytes.as_ref());
19+
result
20+
}
21+
1522
pub fn native_create_signers_for_testing(
1623
_context: &mut NativeContext,
1724
ty_args: Vec<Type>,
@@ -22,7 +29,7 @@ pub fn native_create_signers_for_testing(
2229

2330
let num_signers = pop_arg!(args, u64);
2431
let signers = Value::vector_for_testing_only(
25-
(0..num_signers).map(|i| Value::signer(AccountAddress::new((i as u128).to_le_bytes()))),
32+
(0..num_signers).map(|i| Value::signer(AccountAddress::new(to_le_bytes(i)))),
2633
);
2734

2835
Ok(NativeResult::ok(ONE_GAS_UNIT, smallvec![signers]))

0 commit comments

Comments
 (0)