Skip to content

Commit 718183c

Browse files
authored
Merge pull request #3045 from ProvableHQ/struct-namespace-squashed
Allow external structs.
2 parents 008e1c0 + 4c50a2c commit 718183c

File tree

88 files changed

+2770
-527
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+2770
-527
lines changed

circuit/program/src/data/value/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,24 @@ impl<A: Aleo> Eject for Value<A> {
6868
}
6969
}
7070
}
71+
72+
impl<A: Aleo> From<Plaintext<A>> for Value<A> {
73+
/// Initializes the value from a plaintext.
74+
fn from(plaintext: Plaintext<A>) -> Self {
75+
Self::Plaintext(plaintext)
76+
}
77+
}
78+
79+
impl<A: Aleo> From<Record<A, Plaintext<A>>> for Value<A> {
80+
/// Initializes the value from a record.
81+
fn from(record: Record<A, Plaintext<A>>) -> Self {
82+
Self::Record(record)
83+
}
84+
}
85+
86+
impl<A: Aleo> From<Future<A>> for Value<A> {
87+
/// Initializes the value from a future.
88+
fn from(future: Future<A>) -> Self {
89+
Self::Future(future)
90+
}
91+
}

console/network/src/consensus_heights.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ pub enum ConsensusVersion {
4747
V11 = 11,
4848
/// V12: Prevent connection to forked nodes, disable StringType, enable block timestamp.
4949
V12 = 12,
50+
/// V13: Introduces external structs.
51+
V13 = 13,
5052
}
5153

5254
impl ToBytes for ConsensusVersion {
@@ -71,6 +73,7 @@ impl FromBytes for ConsensusVersion {
7173
10 => Ok(Self::V10),
7274
11 => Ok(Self::V11),
7375
12 => Ok(Self::V12),
76+
13 => Ok(Self::V13),
7477
_ => Err(io_error("Invalid consensus version")),
7578
}
7679
}
@@ -106,6 +109,7 @@ pub const CANARY_V0_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CON
106109
(ConsensusVersion::V10, 8_600_000),
107110
(ConsensusVersion::V11, 9_510_000),
108111
(ConsensusVersion::V12, 10_030_000),
112+
(ConsensusVersion::V13, u32::MAX),
109113
];
110114

111115
/// The consensus version height for `MainnetV0`.
@@ -122,6 +126,7 @@ pub const MAINNET_V0_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CO
122126
(ConsensusVersion::V10, 11_205_000),
123127
(ConsensusVersion::V11, 12_870_000),
124128
(ConsensusVersion::V12, 13_815_000),
129+
(ConsensusVersion::V13, u32::MAX),
125130
];
126131

127132
/// The consensus version heights for `TestnetV0`.
@@ -138,6 +143,7 @@ pub const TESTNET_V0_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CO
138143
(ConsensusVersion::V10, 10_525_000),
139144
(ConsensusVersion::V11, 11_952_000),
140145
(ConsensusVersion::V12, 12_669_000),
146+
(ConsensusVersion::V13, u32::MAX),
141147
];
142148

143149
/// The consensus version heights when the `test_consensus_heights` feature is enabled.
@@ -154,6 +160,7 @@ pub const TEST_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSU
154160
(ConsensusVersion::V10, 13),
155161
(ConsensusVersion::V11, 14),
156162
(ConsensusVersion::V12, 15),
163+
(ConsensusVersion::V13, 16),
157164
];
158165

159166
#[cfg(any(test, feature = "test", feature = "test_consensus_heights"))]

console/program/src/data_types/array_type/bytes.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// limitations under the License.
1515

1616
use super::*;
17-
use crate::{Identifier, LiteralType};
17+
use crate::{Identifier, LiteralType, Locator};
1818

1919
impl<N: Network> FromBytes for ArrayType<N> {
2020
fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
@@ -23,7 +23,8 @@ impl<N: Network> FromBytes for ArrayType<N> {
2323
let element_type = match variant {
2424
0 => PlaintextType::Literal(LiteralType::read_le(&mut reader)?),
2525
1 => PlaintextType::Struct(Identifier::read_le(&mut reader)?),
26-
2.. => return Err(error(format!("Failed to deserialize element type {variant}"))),
26+
2 => PlaintextType::ExternalStruct(Locator::read_le(&mut reader)?),
27+
_ => return Err(error(format!("Failed to deserialize element type {variant}"))),
2728
};
2829

2930
// Read the number of dimensions of the array.
@@ -58,7 +59,7 @@ impl<N: Network> ToBytes for ArrayType<N> {
5859
// Note that the lengths are in the order of the outermost dimension to the innermost dimension.
5960
for _ in 1..N::MAX_DATA_DEPTH {
6061
element_type = match element_type {
61-
PlaintextType::Literal(_) | PlaintextType::Struct(_) => break,
62+
PlaintextType::Literal(_) | PlaintextType::Struct(_) | PlaintextType::ExternalStruct(_) => break,
6263
PlaintextType::Array(array_type) => {
6364
lengths.push(*array_type.length());
6465
array_type.next_element_type().clone()
@@ -81,6 +82,10 @@ impl<N: Network> ToBytes for ArrayType<N> {
8182
1u8.write_le(&mut writer)?;
8283
identifier.write_le(&mut writer)?;
8384
}
85+
PlaintextType::ExternalStruct(locator) => {
86+
2u8.write_le(&mut writer)?;
87+
locator.write_le(&mut writer)?;
88+
}
8489
PlaintextType::Array(_) => {
8590
// This is technically unreachable by definition, however we return an error
8691
// out of an abundance of caution.

console/program/src/data_types/array_type/parse.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,20 @@
1414
// limitations under the License.
1515

1616
use super::*;
17-
use crate::{Identifier, LiteralType};
17+
use crate::{Identifier, LiteralType, Locator};
1818

1919
impl<N: Network> Parser for ArrayType<N> {
2020
/// Parses a string into a literal type.
2121
#[inline]
2222
fn parse(string: &str) -> ParserResult<Self> {
2323
// A helper function to parse the innermost element type.
2424
fn parse_inner_element_type<N: Network>(string: &str) -> ParserResult<PlaintextType<N>> {
25-
alt((map(LiteralType::parse, PlaintextType::from), map(Identifier::parse, PlaintextType::from)))(string)
25+
// Order matters - we shouldn't try to parse Identifier before Locator.
26+
alt((
27+
map(Locator::parse, PlaintextType::from),
28+
map(LiteralType::parse, PlaintextType::from),
29+
map(Identifier::parse, PlaintextType::from),
30+
))(string)
2631
}
2732

2833
// A helper function to parse the length of each dimension.

console/program/src/data_types/finalize_type/size_in_bits.rs

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,41 @@ use super::*;
2020
impl<N: Network> FinalizeType<N> {
2121
/// Returns the number of bits of a finalize type.
2222
/// Note. The plaintext variant is assumed to be an argument of a `Future` and this does not have a "raw" serialization.
23-
pub fn future_size_in_bits<F0, F1>(locator: &Locator<N>, get_struct: &F0, get_future: &F1) -> Result<usize>
23+
pub fn future_size_in_bits<F0, F1, F2>(
24+
locator: &Locator<N>,
25+
get_struct: &F0,
26+
get_external_struct: &F1,
27+
get_future: &F2,
28+
) -> Result<usize>
2429
where
2530
F0: Fn(&Identifier<N>) -> Result<StructType<N>>,
26-
F1: Fn(&Locator<N>) -> Result<Vec<FinalizeType<N>>>,
31+
F1: Fn(&Locator<N>) -> Result<StructType<N>>,
32+
F2: Fn(&Locator<N>) -> Result<Vec<FinalizeType<N>>>,
2733
{
28-
FinalizeType::Future(*locator).size_in_bits_internal(get_struct, get_future, 0)
34+
FinalizeType::Future(*locator).size_in_bits_internal(get_struct, get_external_struct, get_future, 0)
2935
}
3036

3137
/// A helper function to determine the number of bits of a plaintext type, while tracking the depth of the data.
3238
/// Note. The plaintext variant is assumed to be an argument of a `Future` and thus does not have a "raw" serialization.
33-
fn size_in_bits_internal<F0, F1>(&self, get_struct: &F0, get_future: &F1, depth: usize) -> Result<usize>
39+
fn size_in_bits_internal<F0, F1, F2>(
40+
&self,
41+
get_struct: &F0,
42+
get_external_struct: &F1,
43+
get_future: &F2,
44+
depth: usize,
45+
) -> Result<usize>
3446
where
3547
F0: Fn(&Identifier<N>) -> Result<StructType<N>>,
36-
F1: Fn(&Locator<N>) -> Result<Vec<FinalizeType<N>>>,
48+
F1: Fn(&Locator<N>) -> Result<StructType<N>>,
49+
F2: Fn(&Locator<N>) -> Result<Vec<FinalizeType<N>>>,
3750
{
3851
// Ensure that the depth is within the maximum limit.
3952
ensure!(depth <= N::MAX_DATA_DEPTH, "Finalize type depth exceeds maximum limit: {}", N::MAX_DATA_DEPTH);
4053

4154
match self {
42-
Self::Plaintext(plaintext_type) => plaintext_type.size_in_bits_internal(get_struct, depth),
55+
Self::Plaintext(plaintext_type) => {
56+
plaintext_type.size_in_bits_internal(get_struct, get_external_struct, depth)
57+
}
4358
Self::Future(locator) => {
4459
// Initialize the size in bits.
4560
let mut size = 0usize;
@@ -79,7 +94,12 @@ impl<N: Network> FinalizeType<N> {
7994

8095
// Account for the argument bits.
8196
size = size
82-
.checked_add(argument.size_in_bits_internal(get_struct, get_future, depth + 1)?)
97+
.checked_add(argument.size_in_bits_internal(
98+
get_struct,
99+
get_external_struct,
100+
get_future,
101+
depth + 1,
102+
)?)
83103
.ok_or(anyhow!("`size_in_bits` overflowed"))?;
84104
}
85105

@@ -89,11 +109,17 @@ impl<N: Network> FinalizeType<N> {
89109
}
90110

91111
/// Returns the number of raw bits of a finlaize type.
92-
pub fn future_size_in_bits_raw<F0, F1>(locator: &Locator<N>, get_struct: &F0, get_future: &F1) -> Result<usize>
112+
pub fn future_size_in_bits_raw<F0, F1, F2>(
113+
locator: &Locator<N>,
114+
get_struct: &F0,
115+
get_external_struct: &F1,
116+
get_future: &F2,
117+
) -> Result<usize>
93118
where
94119
F0: Fn(&Identifier<N>) -> Result<StructType<N>>,
95-
F1: Fn(&Locator<N>) -> Result<Vec<FinalizeType<N>>>,
120+
F1: Fn(&Locator<N>) -> Result<StructType<N>>,
121+
F2: Fn(&Locator<N>) -> Result<Vec<FinalizeType<N>>>,
96122
{
97-
Self::future_size_in_bits(locator, get_struct, get_future)
123+
Self::future_size_in_bits(locator, get_struct, get_external_struct, get_future)
98124
}
99125
}

console/program/src/data_types/plaintext_type/bytes.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ impl<N: Network> FromBytes for PlaintextType<N> {
2323
0 => Ok(Self::Literal(LiteralType::read_le(&mut reader)?)),
2424
1 => Ok(Self::Struct(Identifier::read_le(&mut reader)?)),
2525
2 => Ok(Self::Array(ArrayType::read_le(&mut reader)?)),
26-
3.. => Err(error(format!("Failed to deserialize annotation variant {variant}"))),
26+
3 => Ok(Self::ExternalStruct(Locator::read_le(&mut reader)?)),
27+
4.. => Err(error(format!("Failed to deserialize plaintext type variant {variant}"))),
2728
}
2829
}
2930
}
@@ -44,6 +45,10 @@ impl<N: Network> ToBytes for PlaintextType<N> {
4445
2u8.write_le(&mut writer)?;
4546
array_type.write_le(&mut writer)
4647
}
48+
Self::ExternalStruct(locator) => {
49+
3u8.write_le(&mut writer)?;
50+
locator.write_le(&mut writer)
51+
}
4752
}
4853
}
4954
}

console/program/src/data_types/plaintext_type/mod.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,49 @@ mod parse;
1818
mod serialize;
1919
mod size_in_bits;
2020

21-
use crate::{ArrayType, Identifier, LiteralType, StructType};
21+
use crate::{ArrayType, Identifier, LiteralType, Locator, ProgramID, StructType};
2222
use snarkvm_console_network::prelude::*;
2323

24-
/// A `PlaintextType` defines the type parameter for a literal, struct, or array.
24+
/// A `PlaintextType` defines the type parameter for a literal, struct, array, or external struct.
2525
#[derive(Clone, PartialEq, Eq, Hash)]
2626
pub enum PlaintextType<N: Network> {
2727
/// A literal type contains its type name.
2828
/// The format of the type is `<type_name>`.
2929
Literal(LiteralType),
30-
/// An struct type contains its identifier.
30+
/// A struct type contains its identifier.
3131
/// The format of the type is `<identifier>`.
3232
Struct(Identifier<N>),
3333
/// An array type contains its element type and length.
3434
/// The format of the type is `[<element_type>; <length>]`.
3535
Array(ArrayType<N>),
36+
/// An external struct type contains its locator.
37+
/// The format of the type is `<program_id>/<identifier>`.
38+
ExternalStruct(Locator<N>),
39+
}
40+
41+
impl<N: Network> PlaintextType<N> {
42+
/// Returns whether this type refers to an external struct.
43+
pub fn contains_external_struct(&self) -> bool {
44+
use PlaintextType::*;
45+
46+
match self {
47+
Literal(..) | Struct(..) => false,
48+
ExternalStruct(..) => true,
49+
Array(array_type) => array_type.base_element_type().contains_external_struct(),
50+
}
51+
}
52+
53+
// Make unqualified structs into external ones with the given `id`.
54+
pub fn qualify(self, id: ProgramID<N>) -> Self {
55+
match self {
56+
PlaintextType::ExternalStruct(..) | PlaintextType::Literal(..) => self,
57+
PlaintextType::Struct(name) => PlaintextType::ExternalStruct(Locator::new(id, name)),
58+
PlaintextType::Array(array_type) => {
59+
let element_type = array_type.next_element_type().clone().qualify(id);
60+
PlaintextType::Array(ArrayType::new(element_type, vec![*array_type.length()]).unwrap())
61+
}
62+
}
63+
}
3664
}
3765

3866
impl<N: Network> From<LiteralType> for PlaintextType<N> {
@@ -49,6 +77,13 @@ impl<N: Network> From<Identifier<N>> for PlaintextType<N> {
4977
}
5078
}
5179

80+
impl<N: Network> From<Locator<N>> for PlaintextType<N> {
81+
/// Initializes a plaintext type from an external struct type.
82+
fn from(locator: Locator<N>) -> Self {
83+
PlaintextType::ExternalStruct(locator)
84+
}
85+
}
86+
5287
impl<N: Network> From<ArrayType<N>> for PlaintextType<N> {
5388
/// Initializes a plaintext type from an array type.
5489
fn from(array: ArrayType<N>) -> Self {
@@ -76,7 +111,7 @@ impl<N: Network> PlaintextType<N> {
76111
/// Returns `true` if the `PlaintextType` is an array and the size exceeds the given maximum.
77112
pub fn exceeds_max_array_size(&self, max_array_size: u32) -> bool {
78113
match self {
79-
Self::Literal(_) | Self::Struct(_) => false,
114+
Self::Literal(_) | Self::Struct(_) | Self::ExternalStruct(_) => false,
80115
Self::Array(array_type) => array_type.exceeds_max_array_size(max_array_size),
81116
}
82117
}

console/program/src/data_types/plaintext_type/parse.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ impl<N: Network> Parser for PlaintextType<N> {
2121
fn parse(string: &str) -> ParserResult<Self> {
2222
// Parse to determine the plaintext type (order matters).
2323
alt((
24+
// Order matters - we shouldn't try to parse Identifier before Locator.
2425
map(ArrayType::parse, |type_| Self::Array(type_)),
26+
map(Locator::parse, |locator| Self::ExternalStruct(locator)),
2527
map(Identifier::parse, |identifier| Self::Struct(identifier)),
2628
map(LiteralType::parse, |type_| Self::Literal(type_)),
2729
))(string)
@@ -60,6 +62,8 @@ impl<N: Network> Display for PlaintextType<N> {
6062
Self::Literal(literal) => Display::fmt(literal, f),
6163
// Prints the struct, i.e. signature
6264
Self::Struct(struct_) => Display::fmt(struct_, f),
65+
// Prints the external struct, i.e. foo.aleo/bar
66+
Self::ExternalStruct(locator) => Display::fmt(locator, f),
6367
// Prints the array type, i.e. [field; 2u32]
6468
Self::Array(array) => Display::fmt(array, f),
6569
}

0 commit comments

Comments
 (0)