Skip to content

Commit d652b33

Browse files
authored
Merge pull request #3173 from ProvableHQ/ensure_records_are_linked
Ensure records exist
2 parents 2ae91a0 + fe21160 commit d652b33

Some content is hidden

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

45 files changed

+3380
-813
lines changed

.circleci/config.yml

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ commands:
9090
parameters:
9191
cache_key:
9292
type: string
93-
default: v4.5.1-rust-1.88.0-snarkvm-cache
93+
default: v4.6.0-rust-1.88.0-snarkvm-cache
9494
steps:
9595
- run:
9696
name: Prepare environment variables and install dependencies
@@ -134,8 +134,8 @@ commands:
134134
clang llvm-dev llvm lld pkg-config xz-utils make libssl-dev libssl-dev
135135
- restore_cache:
136136
keys:
137-
- v4.5.1-rust-1.88.0-deps-{{ checksum "Cargo.lock" }}-
138-
- v4.5.1-rust-1.88.0-deps-
137+
- v4.6.0-rust-1.88.0-deps-{{ checksum "Cargo.lock" }}-
138+
- v4.6.0-rust-1.88.0-deps-
139139
- restore_cache:
140140
keys:
141141
- << parameters.cache_key >>
@@ -145,11 +145,11 @@ commands:
145145
parameters:
146146
cache_key:
147147
type: string
148-
default: v4.5.1-rust-1.88.0-snarkvm-cache
148+
default: v4.6.0-rust-1.88.0-snarkvm-cache
149149
steps:
150150
- run: set +e
151151
- save_cache:
152-
key: v4.5.1-rust-1.88.0-deps-{{ checksum "Cargo.lock" }}
152+
key: v4.6.0-rust-1.88.0-deps-{{ checksum "Cargo.lock" }}
153153
paths:
154154
- /home/circleci/.cache/sccache
155155
- /home/circleci/.cargo/registry
@@ -188,7 +188,7 @@ commands:
188188
condition: << parameters.use_cache >>
189189
steps:
190190
- setup_environment:
191-
cache_key: v4.5.1-rust-1.88.0-<< parameters.workspace_member >><< parameters.cache_key_suffix >>-cache
191+
cache_key: v4.6.0-rust-1.88.0-<< parameters.workspace_member >><< parameters.cache_key_suffix >>-cache
192192

193193
- run:
194194
name: Install debian packages (always)
@@ -436,7 +436,7 @@ commands:
436436
condition: << parameters.use_cache >>
437437
steps:
438438
- clear_environment:
439-
cache_key: v4.5.1-rust-1.88.0-<< parameters.workspace_member >><< parameters.cache_key_suffix >>-cache
439+
cache_key: v4.6.0-rust-1.88.0-<< parameters.workspace_member >><< parameters.cache_key_suffix >>-cache
440440

441441
install_rust_nightly:
442442
description: "Install Rust nightly toolchain"
@@ -1054,7 +1054,7 @@ jobs:
10541054
steps:
10551055
- checkout
10561056
- setup_environment:
1057-
cache_key: v4.5.1-rust-1.88.0-snarkvm-wasm-cache
1057+
cache_key: v4.6.0-rust-1.88.0-snarkvm-wasm-cache
10581058
- run:
10591059
no_output_timeout: 30m
10601060
command: |
@@ -1075,7 +1075,7 @@ jobs:
10751075
# Run the tests
10761076
cd wasm && wasm-pack test --node
10771077
- clear_environment:
1078-
cache_key: v4.5.1-rust-1.88.0-snarkvm-wasm-cache
1078+
cache_key: v4.6.0-rust-1.88.0-snarkvm-wasm-cache
10791079

10801080
check-fmt:
10811081
executor: rust-docker
@@ -1084,21 +1084,21 @@ jobs:
10841084
- checkout
10851085
- install_rust_nightly
10861086
- setup_environment:
1087-
cache_key: v4.5.1-rust-1.88.0-snarkvm-fmt-cache
1087+
cache_key: v4.6.0-rust-1.88.0-snarkvm-fmt-cache
10881088
- run:
10891089
name: Check style
10901090
no_output_timeout: 35m
10911091
command: cargo +nightly fmt --all -- --check
10921092
- clear_environment:
1093-
cache_key: v4.5.1-rust-1.88.0-snarkvm-fmt-cache
1093+
cache_key: v4.6.0-rust-1.88.0-snarkvm-fmt-cache
10941094

10951095
check-unused-dependencies:
10961096
executor: rust-docker
10971097
resource_class: << pipeline.parameters.medium >>
10981098
steps:
10991099
- checkout
11001100
- setup_environment:
1101-
cache_key: v4.5.1-rust-1.88.0-machete-cache
1101+
cache_key: v4.6.0-rust-1.88.0-machete-cache
11021102
- run:
11031103
name: Check for unused dependencies
11041104
no_output_timeout: 10m
@@ -1109,23 +1109,23 @@ jobs:
11091109
fi
11101110
cargo machete
11111111
- clear_environment:
1112-
cache_key: v4.5.1-rust-1.88.0-machete-cache
1112+
cache_key: v4.6.0-rust-1.88.0-machete-cache
11131113

11141114
check-cargo-audit:
11151115
executor: rust-docker
11161116
resource_class: << pipeline.parameters.medium >>
11171117
steps:
11181118
- checkout
11191119
- setup_environment:
1120-
cache_key: v4.5.1-rust-1.88.0-cargo-audit-cache
1120+
cache_key: v4.6.0-rust-1.88.0-cargo-audit-cache
11211121
- run:
11221122
name: Check for security vulnerabilities
11231123
no_output_timeout: 10m
11241124
command: |
11251125
cargo install cargo-audit@0.22.0 --locked --force
11261126
cargo audit -D warnings
11271127
- clear_environment:
1128-
cache_key: v4.5.1-rust-1.88.0-cargo-audit-cache
1128+
cache_key: v4.6.0-rust-1.88.0-cargo-audit-cache
11291129

11301130
check-cargo-semver-checks:
11311131
executor: rust-docker
@@ -1134,22 +1134,22 @@ jobs:
11341134
- checkout:
11351135
method: full
11361136
- setup_environment:
1137-
cache_key: v4.5.1-rust-1.88.0-cargo-semver-checks-cache
1137+
cache_key: v4.6.0-rust-1.88.0-cargo-semver-checks-cache
11381138
- run:
11391139
name: Check for semver violations
11401140
no_output_timeout: 15m
11411141
command: |
11421142
bash ./.circleci/semver-checks.sh
11431143
- clear_environment:
1144-
cache_key: v4.5.1-rust-1.88.0-cargo-semver-checks-cache
1144+
cache_key: v4.6.0-rust-1.88.0-cargo-semver-checks-cache
11451145

11461146
check-clippy:
11471147
executor: rust-docker
11481148
resource_class: << pipeline.parameters.xlarge >>
11491149
steps:
11501150
- checkout
11511151
- setup_environment:
1152-
cache_key: v4.5.1-rust-1.88.0-snarkvm-clippy-cache
1152+
cache_key: v4.6.0-rust-1.88.0-snarkvm-clippy-cache
11531153
- run:
11541154
name: Check Clippy (default features)
11551155
timeout: 20m
@@ -1161,21 +1161,21 @@ jobs:
11611161
command: |
11621162
cargo clippy --workspace --all-targets --all-features -- -D warnings
11631163
- clear_environment:
1164-
cache_key: v4.5.1-rust-1.88.0-snarkvm-clippy-cache
1164+
cache_key: v4.6.0-rust-1.88.0-snarkvm-clippy-cache
11651165

11661166
check-all-targets:
11671167
executor: rust-docker
11681168
resource_class: << pipeline.parameters.small >>
11691169
steps:
11701170
- checkout
11711171
- setup_environment:
1172-
cache_key: v4.5.1-rust-1.88.0-snarkvm-all-targets-cache
1172+
cache_key: v4.6.0-rust-1.88.0-snarkvm-all-targets-cache
11731173
- run:
11741174
name: Check all targets
11751175
no_output_timeout: 35m
11761176
command: cargo check --release --workspace --all-targets
11771177
- clear_environment:
1178-
cache_key: v4.5.1-rust-1.88.0-snarkvm-all-targets-cache
1178+
cache_key: v4.6.0-rust-1.88.0-snarkvm-all-targets-cache
11791179

11801180
verify-windows:
11811181
executor:
@@ -1280,6 +1280,7 @@ workflows:
12801280
or pipeline.git.branch == "testnet"
12811281
or pipeline.git.branch == "mainnet"
12821282
or pipeline.git.branch == "feat/dynamic-dispatch"
1283+
or pipeline.git.branch == "reduce_ci_cost"
12831284
jobs:
12841285
- check-unused-dependencies # This can be cleaned up before releases
12851286
- check-cargo-semver-checks # This can be cleaned up before releases

console/collections/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,6 @@ workspace = true
5252

5353
[features]
5454
serial = [ ]
55+
test-utils = [ ]
5556
locktick = [ "dep:locktick" ]
5657
timer = [ "aleo-std/timer" ]

console/collections/src/merkle_tree/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,20 @@ use std::{collections::BTreeMap, mem};
3636
#[cfg(not(feature = "serial"))]
3737
use rayon::prelude::*;
3838

39+
/// A binary Merkle tree constructed with a leaf-digest hash function and a
40+
/// two-to-one compressing hash function.
41+
///
42+
/// If the number of leaves is less than `2**DEPTH`, the leaf layer is first
43+
/// padded to the next power of 2 with the empty-hash value `e` returned by the
44+
/// implementation of `PathHash::hash_empty()` for `PH`, then a balanced binary
45+
/// tree is built. In concrete terms, at most one `e` leaf is added: the rest
46+
/// are only virtual in that instead nodes with the value `PH::hash_children(e,
47+
/// e)` are added to the next level, which is indeed full of size equal to a
48+
/// power of 2.
49+
///
50+
/// Padding levels are then added as needed to reach the full `DEPTH`, each of
51+
/// which is constructed by hashing the root of the previous level together with
52+
/// `e`.
3953
#[derive(Deserialize, Serialize)]
4054
#[serde(bound = "E: Serialize + DeserializeOwned, LH: Serialize + DeserializeOwned, PH: Serialize + DeserializeOwned")]
4155
pub struct MerkleTree<E: Environment, LH: LeafHash<Hash = PH::Hash>, PH: PathHash<Hash = Field<E>>, const DEPTH: u8> {

console/network/src/consensus_heights.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ pub enum ConsensusVersion {
5454
/// Introduces `aleo::GENERATOR`, `aleo::GENERATOR_POWERS`, `snark.verify` opcodes,
5555
/// and dynamic dispatch, and identifier literal types.
5656
V14 = 14,
57+
/// V15: Introduces the record-existence check.
58+
V15 = 15,
5759
}
5860

5961
impl ToBytes for ConsensusVersion {
@@ -80,6 +82,7 @@ impl FromBytes for ConsensusVersion {
8082
12 => Ok(Self::V12),
8183
13 => Ok(Self::V13),
8284
14 => Ok(Self::V14),
85+
15 => Ok(Self::V15),
8386
_ => Err(io_error("Invalid consensus version")),
8487
}
8588
}
@@ -117,6 +120,7 @@ pub const CANARY_V0_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CON
117120
(ConsensusVersion::V12, 10_030_000),
118121
(ConsensusVersion::V13, 10_881_000),
119122
(ConsensusVersion::V14, u32::MAX),
123+
(ConsensusVersion::V15, u32::MAX),
120124
];
121125

122126
/// The consensus version height for `MainnetV0`.
@@ -135,6 +139,7 @@ pub const MAINNET_V0_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CO
135139
(ConsensusVersion::V12, 13_815_000),
136140
(ConsensusVersion::V13, 16_850_000),
137141
(ConsensusVersion::V14, u32::MAX),
142+
(ConsensusVersion::V15, u32::MAX),
138143
];
139144

140145
/// The consensus version heights for `TestnetV0`.
@@ -153,6 +158,7 @@ pub const TESTNET_V0_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CO
153158
(ConsensusVersion::V12, 12_669_000),
154159
(ConsensusVersion::V13, 14_906_000),
155160
(ConsensusVersion::V14, u32::MAX),
161+
(ConsensusVersion::V15, u32::MAX),
156162
];
157163

158164
/// The consensus version heights when the `test_consensus_heights` feature is enabled.
@@ -171,6 +177,7 @@ pub const TEST_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSU
171177
(ConsensusVersion::V12, 15),
172178
(ConsensusVersion::V13, 16),
173179
(ConsensusVersion::V14, 17),
180+
(ConsensusVersion::V15, 18),
174181
];
175182

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

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ impl<N: Network> PlaintextType<N> {
5757
PlaintextType::Struct(name) => PlaintextType::ExternalStruct(Locator::new(id, name)),
5858
PlaintextType::Array(array_type) => {
5959
let element_type = array_type.next_element_type().clone().qualify(id);
60+
// Safe: the length is preserved from the original array type.
6061
PlaintextType::Array(ArrayType::new(element_type, vec![*array_type.length()]).unwrap())
6162
}
6263
}

synthesizer/process/src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,30 @@ use snarkvm_ledger_block::{Deployment, DeploymentVersion, Execution, Fee, Input,
6969
use snarkvm_ledger_store::{FinalizeStorage, FinalizeStore, atomic_batch_scope};
7070
use snarkvm_synthesizer_program::{
7171
Branch,
72+
CastType,
7273
Command,
7374
FinalizeGlobalState,
7475
FinalizeOperation,
7576
Function,
7677
Instruction,
78+
Operand,
7779
Program,
7880
StackTrait,
7981
};
8082
use snarkvm_synthesizer_snark::{ProvingKey, UniversalSRS, VerifyingKey};
8183
use snarkvm_utilities::{defer, dev_println};
8284

8385
use aleo_std::prelude::{finish, lap, timer};
84-
use indexmap::IndexMap;
86+
use indexmap::{IndexMap, IndexSet};
87+
8588
#[cfg(feature = "locktick")]
8689
use locktick::parking_lot::RwLock;
8790
#[cfg(not(feature = "locktick"))]
8891
use parking_lot::RwLock;
89-
use std::{collections::HashMap, sync::Arc};
92+
use std::{
93+
collections::{HashMap, HashSet},
94+
sync::Arc,
95+
};
9096

9197
// Note: a `Process` and all of its fields are meant to be completely stateless. They have no
9298
// notion of block height or consensus version.

synthesizer/process/src/stack/execute.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
// limitations under the License.
1515

1616
use super::*;
17-
use snarkvm_synthesizer_error::*;
1817

1918
impl<N: Network> Stack<N> {
2019
/// Executes a program closure on the given inputs.
@@ -544,6 +543,10 @@ impl<N: Network> Stack<N> {
544543
// Eject the response.
545544
let response = response.eject_value();
546545

546+
if response.outputs().len() != output_types.len() {
547+
return Err(anyhow!("Number of outputs does not match number of output types").into());
548+
}
549+
547550
// Ensure the outputs matches the expected value types.
548551
response.outputs().iter().zip_eq(&output_types).try_for_each(|(output, output_type)| {
549552
// Ensure the output matches its expected type.

synthesizer/process/src/stack/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ use console::{
7070
types::{Field, Group},
7171
};
7272
use snarkvm_ledger_block::{Deployment, Transaction, Transition};
73+
use snarkvm_synthesizer_error::*;
7374
use snarkvm_synthesizer_program::{
7475
CallOperator,
7576
Closure,

synthesizer/process/src/stack/register_types/initialize.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ impl<N: Network> RegisterTypes<N> {
4545
// Step 3. Check the outputs are well-formed.
4646
for output in closure.outputs() {
4747
// Ensure the closure output register is not a static record.
48-
// Dynamic records are allowed as closure outputs.
48+
// ExternalRecord and DynamicRecord are disallowed at V15+ deployment time (see `VM::check_transaction`).
4949
ensure!(
5050
!matches!(output.register_type(), RegisterType::Record(..)),
51-
"Closure outputs do not support static records"
51+
"Closure outputs do not support records"
5252
);
5353

5454
// Check the output operand type.

synthesizer/process/src/trace/translation/assignment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ pub struct TranslationAssignment<N: Network> {
7676
/// Irrelevant if `is_to_static` is false or `is_external_record` is true.
7777
pub(crate) gamma: Option<Group<N>>,
7878
/// Index of the input operand or output destination that contains the (dynamic and static) record.
79-
/// Note: The first three dynamic.call operands are reserved for call-related data,
79+
/// Note: The first three call.dynamic operands are reserved for call-related data,
8080
/// however this operand index still starts at 0 and is the same for caller and callee.
8181
pub(crate) record_register_index: u16,
8282
/// The ID of the dynamic record.

0 commit comments

Comments
 (0)