diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25438f9e861..a0928949d7a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -253,6 +253,18 @@ jobs: - name: Cargo Run E2E Tests (EVM) run: cargo run --locked --release --bin test -- --target evm --locked + cargo-run-e2e-test-midenvm: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_VERSION }} + - uses: Swatinem/rust-cache@v2 + - name: Cargo Run E2E Tests (EVM) + run: cargo run --locked --release --bin test -- --target midenvm --locked + # TODO: Remove this upon merging std tests with the rest of the E2E tests. cargo-test-lib-std: runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index 64d57a87d10..dd01a2d4c76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -365,7 +365,21 @@ checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" dependencies = [ "arrayref", "arrayvec 0.5.2", - "constant_time_eq", + "constant_time_eq 0.1.5", +] + +[[package]] +name = "blake3" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +dependencies = [ + "arrayref", + "arrayvec 0.7.2", + "cc", + "cfg-if 1.0.0", + "constant_time_eq 0.2.4", + "digest 0.10.6", ] [[package]] @@ -795,6 +809,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +[[package]] +name = "constant_time_eq" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ad85c1f65dc7b37604eb0e89748faf0b9653065f2a8ef69f96a687ec1e9279" + [[package]] name = "convert_case" version = "0.4.0" @@ -3103,6 +3123,100 @@ dependencies = [ "autocfg", ] +[[package]] +name = "miden" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d8a25e092075f58af207e2a42bad5fbbf40c5200f13d2432a806db751a52b5" +dependencies = [ + "log", + "miden-air", + "miden-assembly", + "miden-core", + "miden-processor", + "miden-prover", + "miden-stdlib", + "miden-verifier", +] + +[[package]] +name = "miden-air" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5046ab97d8c2b7136601e9430fd0a14e7d6c6cdd648c90c1e6b39186a38b9a8b" +dependencies = [ + "miden-core", + "winter-air", +] + +[[package]] +name = "miden-assembly" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a04eec160cbd5cf3051ad16a244c3d83e648eddbd3349120dc069f6e309259dc" +dependencies = [ + "miden-core", + "num_enum", + "winter-crypto", +] + +[[package]] +name = "miden-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75a2446684f44e61afb27bbdbf2458e8ec58c5c55d9bd202981d7cd265f7cf4" +dependencies = [ + "winter-crypto", + "winter-math", + "winter-utils", +] + +[[package]] +name = "miden-processor" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb7a467447a7d6236f3971f91f8c47c8880a01a43c29b0b08285ec50454f02ed" +dependencies = [ + "log", + "miden-core", + "winter-prover", +] + +[[package]] +name = "miden-prover" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2343eaf338770b78fe421f36a3445bb491123e0787006dfa2b98788cd6440ec6" +dependencies = [ + "log", + "miden-air", + "miden-core", + "miden-processor", + "winter-prover", +] + +[[package]] +name = "miden-stdlib" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b2a52fd1a44b136dbce7a513ebe5a407dfebc17160af8a2707383df731fc098" +dependencies = [ + "miden-assembly", + "miden-core", +] + +[[package]] +name = "miden-verifier" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d942d5b0bdcad47359d52534ef6fbccebffc0c713d2c7ca65ab603c7965c0a8b" +dependencies = [ + "miden-air", + "miden-assembly", + "miden-core", + "winter-verifier", +] + [[package]] name = "mime" version = "0.3.16" @@ -4143,7 +4257,7 @@ checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" dependencies = [ "base64 0.13.1", "blake2b_simd", - "constant_time_eq", + "constant_time_eq 0.1.5", "crossbeam-utils", ] @@ -4806,6 +4920,7 @@ dependencies = [ "im", "itertools", "lazy_static", + "miden-core", "pest", "pest_derive", "petgraph", @@ -5130,6 +5245,7 @@ dependencies = [ "futures", "gag", "hex", + "miden", "prettydiff 0.6.2", "rand", "regex", @@ -6000,6 +6116,83 @@ dependencies = [ "winapi", ] +[[package]] +name = "winter-air" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef91b335c5fefa4e6d3c6274de75a7744b4eecae2d7ee3778c23570f35f83396" +dependencies = [ + "winter-crypto", + "winter-fri", + "winter-math", + "winter-utils", +] + +[[package]] +name = "winter-crypto" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd17ea728ff42185c54dfbabaafd0b442207df6b2cc60f74c607d8c01e9c4db" +dependencies = [ + "blake3", + "sha3 0.10.6", + "winter-math", + "winter-utils", +] + +[[package]] +name = "winter-fri" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2473f8b2c5c553e9f9d4d94b3b7a1e75806b4cdc964004f9bde4b5fc07c10c87" +dependencies = [ + "winter-crypto", + "winter-math", + "winter-utils", +] + +[[package]] +name = "winter-math" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824b459961e5d679a1eb62ec1a71c85ac25c5d3bfd126874fcd32b591202d896" +dependencies = [ + "winter-utils", +] + +[[package]] +name = "winter-prover" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831583fd662f49f23ea39427aba20a9b5ab6326230f7994e843d2bd34524411" +dependencies = [ + "log", + "winter-air", + "winter-crypto", + "winter-fri", + "winter-math", + "winter-utils", +] + +[[package]] +name = "winter-utils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f0dbf7ca6aa5893b59928718bf1e7dbe7279bb277b5aa4c4898ddf5004f9417" + +[[package]] +name = "winter-verifier" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "922be4651b76aa80e132386a97d23788e2bc542d37b3c187a39998876a8094b6" +dependencies = [ + "winter-air", + "winter-crypto", + "winter-fri", + "winter-math", + "winter-utils", +] + [[package]] name = "wyz" version = "0.5.1" diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 13b6cecc9db..f91184e37c3 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -432,6 +432,8 @@ impl BuiltPackage { res? } } + // TODO? + ProgramABI::MidenVM(_) => (), } info!(" Bytecode size: {} bytes", self.bytecode.len()); @@ -1727,6 +1729,8 @@ pub fn compile( ProgramABI::Evm(ops) } + + BuildTarget::MidenVM => ProgramABI::MidenVM(()), }; let entries = asm_res diff --git a/sway-core/Cargo.toml b/sway-core/Cargo.toml index 3025de63c20..8567e1e2579 100644 --- a/sway-core/Cargo.toml +++ b/sway-core/Cargo.toml @@ -24,6 +24,7 @@ hex = { version = "0.4", optional = true } im = "15.0" itertools = "0.10" lazy_static = "1.4" +miden-core = "0.3.0" pest = "2.1.3" pest_derive = "2.1" petgraph = "0.6" diff --git a/sway-core/src/asm_generation/abi.rs b/sway-core/src/asm_generation/abi.rs index 5a45ecdb811..4dd5e2bc28a 100644 --- a/sway-core/src/asm_generation/abi.rs +++ b/sway-core/src/asm_generation/abi.rs @@ -4,4 +4,5 @@ use super::EvmAbiResult; pub enum ProgramABI { Fuel(fuel_abi_types::program_abi::ProgramABI), Evm(EvmAbiResult), + MidenVM(()), } diff --git a/sway-core/src/asm_generation/asm_builder.rs b/sway-core/src/asm_generation/asm_builder.rs index 5c511532625..ff1f4f8827a 100644 --- a/sway-core/src/asm_generation/asm_builder.rs +++ b/sway-core/src/asm_generation/asm_builder.rs @@ -2,11 +2,15 @@ use sway_ir::Function; use crate::{asm_lang::Label, CompileResult}; -use super::{evm::EvmAsmBuilderResult, fuel::fuel_asm_builder::FuelAsmBuilderResult}; +use super::{ + evm::EvmAsmBuilderResult, fuel::fuel_asm_builder::FuelAsmBuilderResult, + miden_vm::MidenVMAsmBuilderResult, +}; pub enum AsmBuilderResult { Fuel(FuelAsmBuilderResult), Evm(EvmAsmBuilderResult), + MidenVM(MidenVMAsmBuilderResult), } pub trait AsmBuilder { diff --git a/sway-core/src/asm_generation/finalized_asm.rs b/sway-core/src/asm_generation/finalized_asm.rs index ff12f21e911..8434ecdaaef 100644 --- a/sway-core/src/asm_generation/finalized_asm.rs +++ b/sway-core/src/asm_generation/finalized_asm.rs @@ -1,4 +1,5 @@ use super::instruction_set::InstructionSet; +use super::ToMidenBytecode; use super::{ fuel::{checks, data_section::DataSection}, ProgramABI, ProgramKind, @@ -73,6 +74,14 @@ impl FinalizedAsm { ) } } + InstructionSet::MidenVM { ops } => ok( + CompiledBytecode { + bytecode: ops.to_bytecode().into(), + config_const_offsets: Default::default(), + }, + vec![], + vec![], + ), } } } @@ -192,5 +201,6 @@ pub fn check_invalid_opcodes(asm: &FinalizedAsm) -> CompileResult<()> { ProgramKind::Predicate => checks::check_predicate_opcodes(&ops[..]), }, InstructionSet::Evm { ops: _ } => ok((), vec![], vec![]), + InstructionSet::MidenVM { ops: _ } => ok((), vec![], vec![]), } } diff --git a/sway-core/src/asm_generation/from_ir.rs b/sway-core/src/asm_generation/from_ir.rs index c03ebecd312..864bd7c6397 100644 --- a/sway-core/src/asm_generation/from_ir.rs +++ b/sway-core/src/asm_generation/from_ir.rs @@ -8,6 +8,7 @@ use super::{ register_sequencer::RegisterSequencer, }, programs::{AbstractEntry, AbstractProgram, FinalProgram, ProgramKind}, + MidenVMAsmBuilder, }; use crate::{err, ok, BuildConfig, BuildTarget, CompileResult, CompileWarning}; @@ -82,6 +83,7 @@ fn compile_module_to_asm( context, )), BuildTarget::EVM => Box::new(EvmAsmBuilder::new(kind, context)), + BuildTarget::MidenVM => Box::new(MidenVMAsmBuilder::new(kind, context)), }; // Pre-create labels for all functions before we generate other code, so we can call them @@ -159,6 +161,7 @@ fn compile_module_to_asm( ops: result.ops, abi: result.abi, }, + AsmBuilderResult::MidenVM(result) => FinalProgram::MidenVM { ops: result.ops }, }; ok(final_program, warnings, errors) diff --git a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs index 52f700eaf64..eb3badb1c55 100644 --- a/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs +++ b/sway-core/src/asm_generation/fuel/fuel_asm_builder.rs @@ -2072,8 +2072,8 @@ impl<'ir> FuelAsmBuilder<'ir> { }) } - // Same as `opt_value_to_register` but returns a new register if no register is found or if - // `value` is not a constant. + /// Same as [`opt_value_to_register`] but returns a new register if no register is found or if + /// `value` is not a constant. pub(super) fn value_to_register(&mut self, value: &Value) -> VirtualRegister { match self.opt_value_to_register(value) { Some(reg) => reg, diff --git a/sway-core/src/asm_generation/instruction_set.rs b/sway-core/src/asm_generation/instruction_set.rs index c96c3f69df0..6e5f007e305 100644 --- a/sway-core/src/asm_generation/instruction_set.rs +++ b/sway-core/src/asm_generation/instruction_set.rs @@ -4,8 +4,15 @@ use std::fmt; /// An [InstructionSet] is produced by allocating registers on an [AbstractInstructionSet]. #[derive(Clone)] pub enum InstructionSet { - Fuel { ops: Vec }, - Evm { ops: Vec }, + Fuel { + ops: Vec, + }, + Evm { + ops: Vec, + }, + MidenVM { + ops: Vec, + }, } impl fmt::Display for InstructionSet { @@ -24,6 +31,12 @@ impl fmt::Display for InstructionSet { .map(|x| format!("{x}")) .collect::>() .join("\n"), + InstructionSet::MidenVM { ops } => { + ops.iter() + .map(|x| format!("{x}")) + .collect::>() + .join("\n") + } } ) } diff --git a/sway-core/src/asm_generation/miden_vm.rs b/sway-core/src/asm_generation/miden_vm.rs new file mode 100644 index 00000000000..53e83db203a --- /dev/null +++ b/sway-core/src/asm_generation/miden_vm.rs @@ -0,0 +1,2 @@ +mod miden_vm_asm_builder; +pub use miden_vm_asm_builder::*; diff --git a/sway-core/src/asm_generation/miden_vm/miden_vm_asm_builder.rs b/sway-core/src/asm_generation/miden_vm/miden_vm_asm_builder.rs new file mode 100644 index 00000000000..913d5bbd572 --- /dev/null +++ b/sway-core/src/asm_generation/miden_vm/miden_vm_asm_builder.rs @@ -0,0 +1,652 @@ +#![allow(dead_code)] +use std::{collections::HashMap, sync::Arc}; +mod miden_op; +pub use miden_op::MidenAsmOp; + +use crate::{ + asm_generation::{ + asm_builder::{AsmBuilder, AsmBuilderResult}, + from_ir::StateAccessType, + miden_vm::miden_vm_asm_builder::miden_op::{MidenStackValue, Push}, + ProgramKind, + }, + asm_lang::Label, + error::*, + metadata::MetadataManager, +}; + +use sway_error::error::CompileError; +use sway_ir::{Context, *}; +use sway_types::Span; + +pub use miden_op::DirectOp; + +#[derive(Default)] +pub struct MidenVMAsmSection { + ops: Vec, +} + +/// A procedure block is used to define a frequently-used sequence of instructions. A procedure must +/// start with a proc.