mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-06-26 00:49:27 +00:00
refactor!(artifacts): keep lee and lez artifacts separated
This commit is contained in:
parent
066ffdd51a
commit
d3e507f25d
236
Cargo.lock
generated
236
Cargo.lock
generated
@ -106,6 +106,17 @@ version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "amm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"amm_core",
|
||||
"lee",
|
||||
"lee_core",
|
||||
"programs",
|
||||
"token_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "amm_core"
|
||||
version = "0.1.0"
|
||||
@ -116,16 +127,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "amm_program"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"amm_core",
|
||||
"lee",
|
||||
"lee_core",
|
||||
"token_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
@ -513,6 +514,24 @@ version = "0.7.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4858a9d740c5007a9069007c3b4e91152d0506f13c1b31dd49051fd537656156"
|
||||
|
||||
[[package]]
|
||||
name = "associated_token_account"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"associated_token_account_core",
|
||||
"lee_core",
|
||||
"token_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "associated_token_account_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lee_core",
|
||||
"risc0-zkvm",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "astral-tokio-tar"
|
||||
version = "0.6.2"
|
||||
@ -665,24 +684,6 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ata_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lee_core",
|
||||
"risc0-zkvm",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ata_program"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ata_core",
|
||||
"lee_core",
|
||||
"token_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-polyfill"
|
||||
version = "1.0.3"
|
||||
@ -751,6 +752,14 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "authenticated_transfer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"authenticated_transfer_core",
|
||||
"lee_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "authenticated_transfer_core"
|
||||
version = "0.1.0"
|
||||
@ -1137,6 +1146,16 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bridge"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"authenticated_transfer_core",
|
||||
"bridge_core",
|
||||
"lee_core",
|
||||
"vault_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bridge_core"
|
||||
version = "0.1.0"
|
||||
@ -1154,6 +1173,14 @@ dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "build_utils"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"risc0-binfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.20.3"
|
||||
@ -1444,6 +1471,14 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
|
||||
|
||||
[[package]]
|
||||
name = "clock"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clock_core",
|
||||
"lee_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clock_core"
|
||||
version = "0.1.0"
|
||||
@ -1514,9 +1549,11 @@ dependencies = [
|
||||
"lee_core",
|
||||
"log",
|
||||
"logos-blockchain-common-http-client",
|
||||
"programs",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"sha2",
|
||||
"system_accounts",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
@ -1932,7 +1969,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"amm_core",
|
||||
"anyhow",
|
||||
"ata_core",
|
||||
"associated_token_account_core",
|
||||
"authenticated_transfer_core",
|
||||
"borsh",
|
||||
"clap",
|
||||
@ -1940,9 +1977,11 @@ dependencies = [
|
||||
"criterion",
|
||||
"lee",
|
||||
"lee_core",
|
||||
"programs",
|
||||
"risc0-zkvm",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"test_programs",
|
||||
"token_core",
|
||||
]
|
||||
|
||||
@ -2632,6 +2671,16 @@ version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
|
||||
|
||||
[[package]]
|
||||
name = "faucet"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"authenticated_transfer_core",
|
||||
"faucet_core",
|
||||
"lee_core",
|
||||
"vault_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "faucet_core"
|
||||
version = "0.1.0"
|
||||
@ -3959,7 +4008,7 @@ name = "integration_tests"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ata_core",
|
||||
"associated_token_account_core",
|
||||
"authenticated_transfer_core",
|
||||
"borsh",
|
||||
"bridge_core",
|
||||
@ -3980,12 +4029,15 @@ dependencies = [
|
||||
"logos-blockchain-key-management-system-service",
|
||||
"logos-blockchain-zone-sdk",
|
||||
"num-bigint 0.4.6",
|
||||
"programs",
|
||||
"reqwest",
|
||||
"sequencer_core",
|
||||
"sequencer_service_rpc",
|
||||
"serde_json",
|
||||
"system_accounts",
|
||||
"tempfile",
|
||||
"test_fixtures",
|
||||
"test_programs",
|
||||
"token_core",
|
||||
"tokio",
|
||||
"vault_core",
|
||||
@ -4499,12 +4551,9 @@ name = "lee"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"authenticated_transfer_core",
|
||||
"borsh",
|
||||
"bridge_core",
|
||||
"clock_core",
|
||||
"build_utils",
|
||||
"env_logger",
|
||||
"faucet_core",
|
||||
"hex",
|
||||
"hex-literal 1.1.0",
|
||||
"k256",
|
||||
@ -4512,13 +4561,12 @@ dependencies = [
|
||||
"log",
|
||||
"rand 0.8.6",
|
||||
"risc0-binfmt",
|
||||
"risc0-build",
|
||||
"risc0-zkvm",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"sha2",
|
||||
"test-case",
|
||||
"test_program_methods",
|
||||
"test_methods",
|
||||
"thiserror 2.0.18",
|
||||
"token_core",
|
||||
]
|
||||
@ -7112,6 +7160,23 @@ version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||
|
||||
[[package]]
|
||||
name = "pinata"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lee_core",
|
||||
"risc0-zkvm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pinata_token"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lee_core",
|
||||
"risc0-zkvm",
|
||||
"token_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs1"
|
||||
version = "0.7.5"
|
||||
@ -7265,6 +7330,14 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "privacy_preserving_circuit"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lee_core",
|
||||
"risc0-zkvm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "3.5.0"
|
||||
@ -7366,30 +7439,24 @@ dependencies = [
|
||||
"wallet",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "program_methods"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"risc0-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "programs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"amm",
|
||||
"amm_core",
|
||||
"amm_program",
|
||||
"ata_core",
|
||||
"ata_program",
|
||||
"associated_token_account",
|
||||
"associated_token_account_core",
|
||||
"authenticated_transfer_core",
|
||||
"bridge_core",
|
||||
"build_utils",
|
||||
"clock_core",
|
||||
"faucet_core",
|
||||
"lee",
|
||||
"lee_core",
|
||||
"risc0-zkvm",
|
||||
"serde",
|
||||
"token",
|
||||
"token_core",
|
||||
"token_program",
|
||||
"vault_core",
|
||||
]
|
||||
|
||||
@ -8842,14 +8909,17 @@ dependencies = [
|
||||
"logos-blockchain-zone-sdk",
|
||||
"mempool",
|
||||
"num-bigint 0.4.6",
|
||||
"programs",
|
||||
"rand 0.8.6",
|
||||
"risc0-zkvm",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"storage",
|
||||
"system_accounts",
|
||||
"tempfile",
|
||||
"test_program_methods",
|
||||
"test_programs",
|
||||
"testnet_initial_state",
|
||||
"token_core",
|
||||
"tokio",
|
||||
"url",
|
||||
"vault_core",
|
||||
@ -8870,6 +8940,7 @@ dependencies = [
|
||||
"lee",
|
||||
"log",
|
||||
"mempool",
|
||||
"programs",
|
||||
"sequencer_core",
|
||||
"sequencer_service_protocol",
|
||||
"sequencer_service_rpc",
|
||||
@ -9541,6 +9612,17 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system_accounts"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bridge_core",
|
||||
"clock_core",
|
||||
"faucet_core",
|
||||
"lee_core",
|
||||
"programs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tachys"
|
||||
version = "0.2.15"
|
||||
@ -9663,6 +9745,7 @@ dependencies = [
|
||||
"lee",
|
||||
"lee_core",
|
||||
"log",
|
||||
"programs",
|
||||
"sequencer_core",
|
||||
"sequencer_service",
|
||||
"sequencer_service_rpc",
|
||||
@ -9676,14 +9759,23 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test_program_methods"
|
||||
name = "test_methods"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"risc0-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test_programs"
|
||||
name = "test_methods_guests"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lee_core",
|
||||
"risc0-zkvm",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test_program_guests"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"authenticated_transfer_core",
|
||||
@ -9691,7 +9783,14 @@ dependencies = [
|
||||
"faucet_core",
|
||||
"lee_core",
|
||||
"risc0-zkvm",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test_programs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lee",
|
||||
"risc0-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -9731,11 +9830,12 @@ dependencies = [
|
||||
name = "testnet_initial_state"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"common",
|
||||
"key_protocol",
|
||||
"lee",
|
||||
"lee_core",
|
||||
"programs",
|
||||
"serde",
|
||||
"system_accounts",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -9871,6 +9971,14 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "token"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lee_core",
|
||||
"token_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "token_core"
|
||||
version = "0.1.0"
|
||||
@ -9880,14 +9988,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "token_program"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lee_core",
|
||||
"token_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.52.3"
|
||||
@ -10684,6 +10784,15 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||
|
||||
[[package]]
|
||||
name = "vault"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"authenticated_transfer_core",
|
||||
"lee_core",
|
||||
"vault_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vault_core"
|
||||
version = "0.1.0"
|
||||
@ -10721,8 +10830,8 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"amm_core",
|
||||
"anyhow",
|
||||
"associated_token_account_core",
|
||||
"async-stream",
|
||||
"ata_core",
|
||||
"authenticated_transfer_core",
|
||||
"base58",
|
||||
"bincode",
|
||||
@ -10744,6 +10853,7 @@ dependencies = [
|
||||
"lee_core",
|
||||
"log",
|
||||
"optfield",
|
||||
"programs",
|
||||
"pyo3",
|
||||
"rand 0.8.6",
|
||||
"rpassword",
|
||||
@ -10751,6 +10861,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"system_accounts",
|
||||
"tempfile",
|
||||
"testnet_initial_state",
|
||||
"thiserror 2.0.18",
|
||||
@ -10771,6 +10882,7 @@ dependencies = [
|
||||
"key_protocol",
|
||||
"lee",
|
||||
"lee_core",
|
||||
"programs",
|
||||
"risc0-zkvm",
|
||||
"sequencer_service_rpc",
|
||||
"serde_json",
|
||||
|
||||
85
Cargo.toml
85
Cargo.toml
@ -5,25 +5,17 @@ license = "MIT or Apache-2.0"
|
||||
resolver = "3"
|
||||
members = [
|
||||
"integration_tests",
|
||||
|
||||
"lez/storage",
|
||||
"lee/key_protocol",
|
||||
"lee/state_machine",
|
||||
"lee/state_machine/core",
|
||||
"lez/mempool",
|
||||
"lez/wallet",
|
||||
"lez/wallet-ffi",
|
||||
"lez/common",
|
||||
"programs/amm/core",
|
||||
"programs/amm",
|
||||
"programs/clock/core",
|
||||
"programs/token/core",
|
||||
"programs/token",
|
||||
"programs/associated_token_account/core",
|
||||
"programs/associated_token_account",
|
||||
"programs/authenticated_transfer/core",
|
||||
"programs/faucet/core",
|
||||
"programs/bridge/core",
|
||||
"programs/vault/core",
|
||||
"lee/privacy_preserving_circuit",
|
||||
"lee/state_machine/test_methods",
|
||||
"lee/state_machine/test_methods/guest",
|
||||
|
||||
"lez",
|
||||
"lez/system_accounts",
|
||||
"lez/sequencer/core",
|
||||
"lez/sequencer/service",
|
||||
"lez/sequencer/service/protocol",
|
||||
@ -33,18 +25,36 @@ members = [
|
||||
"lez/indexer/service/protocol",
|
||||
"lez/indexer/service/rpc",
|
||||
"lez/explorer_service",
|
||||
"program_methods",
|
||||
"program_methods/guest",
|
||||
"test_program_methods",
|
||||
"test_program_methods/guest",
|
||||
"lez/testnet_initial_state",
|
||||
"lez/indexer/ffi",
|
||||
"lez/keycard_wallet",
|
||||
"lez/mempool",
|
||||
"lez/wallet",
|
||||
"lez/wallet-ffi",
|
||||
"lez/common",
|
||||
"lez/programs",
|
||||
"lez/programs/amm",
|
||||
"lez/programs/associated_token_account",
|
||||
"lez/programs/authenticated_transfer",
|
||||
"lez/programs/bridge",
|
||||
"lez/programs/clock",
|
||||
"lez/programs/faucet",
|
||||
"lez/programs/pinata",
|
||||
"lez/programs/pinata_token",
|
||||
"lez/programs/token",
|
||||
"lez/programs/vault",
|
||||
|
||||
"test_programs",
|
||||
"test_programs/guest",
|
||||
|
||||
"examples/program_deployment",
|
||||
"examples/program_deployment/methods",
|
||||
"examples/program_deployment/methods/guest",
|
||||
"lez/testnet_initial_state",
|
||||
"lez/indexer/ffi",
|
||||
"lez",
|
||||
"lez/keycard_wallet",
|
||||
|
||||
"build_utils",
|
||||
|
||||
"test_fixtures",
|
||||
|
||||
"tools/cycle_bench",
|
||||
"tools/crypto_primitives_bench",
|
||||
"tools/integration_bench",
|
||||
@ -69,18 +79,23 @@ wallet = { path = "lez/wallet" }
|
||||
wallet-ffi = { path = "lez/wallet-ffi", default-features = false }
|
||||
indexer_ffi = { path = "lez/indexer/ffi" }
|
||||
lez = { path = "lez" }
|
||||
clock_core = { path = "programs/clock/core" }
|
||||
token_core = { path = "programs/token/core" }
|
||||
token_program = { path = "programs/token" }
|
||||
amm_core = { path = "programs/amm/core" }
|
||||
amm_program = { path = "programs/amm" }
|
||||
ata_core = { path = "programs/associated_token_account/core" }
|
||||
ata_program = { path = "programs/associated_token_account" }
|
||||
authenticated_transfer_core = { path = "programs/authenticated_transfer/core" }
|
||||
faucet_core = { path = "programs/faucet/core" }
|
||||
bridge_core = { path = "programs/bridge/core" }
|
||||
vault_core = { path = "programs/vault/core" }
|
||||
test_program_methods = { path = "test_program_methods" }
|
||||
programs = { path = "lez/programs", default-features = false, features = [
|
||||
"artifacts",
|
||||
] }
|
||||
system_accounts = { path = "lez/system_accounts" }
|
||||
clock_core = { path = "lez/programs/clock/core" }
|
||||
token_core = { path = "lez/programs/token/core" }
|
||||
token_program = { path = "lez/programs/token" }
|
||||
amm_core = { path = "lez/programs/amm/core" }
|
||||
amm_program = { path = "lez/programs/amm" }
|
||||
associated_token_account_core = { path = "lez/programs/associated_token_account/core" }
|
||||
ata_program = { path = "lez/programs/associated_token_account" }
|
||||
authenticated_transfer_core = { path = "lez/programs/authenticated_transfer/core" }
|
||||
faucet_core = { path = "lez/programs/faucet/core" }
|
||||
bridge_core = { path = "lez/programs/bridge/core" }
|
||||
vault_core = { path = "lez/programs/vault/core" }
|
||||
build_utils = { path = "build_utils" }
|
||||
test_programs = { path = "test_programs" }
|
||||
testnet_initial_state = { path = "lez/testnet_initial_state" }
|
||||
keycard_wallet = { path = "lez/keycard_wallet" }
|
||||
test_fixtures = { path = "test_fixtures" }
|
||||
|
||||
22
Justfile
22
Justfile
@ -4,19 +4,25 @@ default:
|
||||
@just --list
|
||||
|
||||
# ---- Configuration ----
|
||||
METHODS_PATH := "program_methods"
|
||||
TEST_METHODS_PATH := "test_program_methods"
|
||||
ARTIFACTS := "artifacts"
|
||||
|
||||
# Build risc0 program artifacts.
|
||||
build-artifacts:
|
||||
@echo "🔨 Building artifacts"
|
||||
@for methods_path in {{METHODS_PATH}} {{TEST_METHODS_PATH}}; do \
|
||||
echo "Building artifacts for $methods_path"; \
|
||||
CARGO_TARGET_DIR=target/$methods_path cargo risczero build --manifest-path $methods_path/guest/Cargo.toml; \
|
||||
mkdir -p {{ARTIFACTS}}/$methods_path; \
|
||||
cp target/$methods_path/riscv32im-risc0-zkvm-elf/docker/*.bin {{ARTIFACTS}}/$methods_path; \
|
||||
done
|
||||
@rm -rf {{ARTIFACTS}}
|
||||
@just build-artifact lee/privacy_preserving_circuit
|
||||
@just build-artifact lez/programs programs
|
||||
|
||||
build-artifact methods_path features="":
|
||||
@echo "Building artifacts for {{methods_path}}"
|
||||
@rm -rf target/{{methods_path}}/riscv32im-risc0-zkvm-elf/docker/*.bin
|
||||
@if [ "{{features}}" = "" ]; then \
|
||||
CARGO_TARGET_DIR=target/{{methods_path}} cargo risczero build --manifest-path {{methods_path}}/Cargo.toml; \
|
||||
else \
|
||||
CARGO_TARGET_DIR=target/{{methods_path}} cargo risczero build --no-default-features --features {{features}} --manifest-path {{methods_path}}/Cargo.toml; \
|
||||
fi
|
||||
@mkdir -p {{ARTIFACTS}}/{{methods_path}}
|
||||
@cp target/{{methods_path}}/riscv32im-risc0-zkvm-elf/docker/*.bin {{ARTIFACTS}}/{{methods_path}}
|
||||
|
||||
# Format codebase.
|
||||
fmt:
|
||||
|
||||
Binary file not shown.
BIN
artifacts/lez/programs/amm.bin
Normal file
BIN
artifacts/lez/programs/amm.bin
Normal file
Binary file not shown.
BIN
artifacts/lez/programs/associated_token_account.bin
Normal file
BIN
artifacts/lez/programs/associated_token_account.bin
Normal file
Binary file not shown.
BIN
artifacts/lez/programs/authenticated_transfer.bin
Normal file
BIN
artifacts/lez/programs/authenticated_transfer.bin
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
artifacts/lez/programs/faucet.bin
Normal file
BIN
artifacts/lez/programs/faucet.bin
Normal file
Binary file not shown.
Binary file not shown.
BIN
artifacts/lez/programs/pinata_token.bin
Normal file
BIN
artifacts/lez/programs/pinata_token.bin
Normal file
Binary file not shown.
BIN
artifacts/lez/programs/token.bin
Normal file
BIN
artifacts/lez/programs/token.bin
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
11
build_utils/Cargo.toml
Normal file
11
build_utils/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "build_utils"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
license = { workspace = true }
|
||||
|
||||
[lints]
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
risc0-binfmt = "3.0.2"
|
||||
69
build_utils/src/lib.rs
Normal file
69
build_utils/src/lib.rs
Normal file
@ -0,0 +1,69 @@
|
||||
//! Utilities for build-scripts.
|
||||
|
||||
use std::{env, fmt::Write as _, fs, path::PathBuf};
|
||||
|
||||
use anyhow::{Context as _, Result, bail};
|
||||
|
||||
/// Include artifact binaries as byte arrays and their corresponding image IDs as u32 arrays in a
|
||||
/// generated Rust module.
|
||||
///
|
||||
/// The `artifacts_sub_dir` parameter specifies the subdirectory under `artifacts/`.
|
||||
///
|
||||
/// Caller should include resulting module as follows:
|
||||
///
|
||||
/// ```
|
||||
/// mod guests {
|
||||
/// include!(concat!(env!("OUT_DIR"), "/artifacts_sub_dir/mod.rs"));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn include_artifacts(artifacts_sub_dir: &str) -> Result<()> {
|
||||
let manifest_dir = PathBuf::from(std::env!("CARGO_MANIFEST_DIR"));
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
|
||||
let mod_dir = out_dir.join(artifacts_sub_dir);
|
||||
let mod_file = mod_dir.join("mod.rs");
|
||||
let artifacts_dir = manifest_dir.join(format!("../artifacts/{artifacts_sub_dir}/"));
|
||||
|
||||
println!("cargo:rerun-if-changed={}", artifacts_dir.display());
|
||||
|
||||
let bins = fs::read_dir(&artifacts_dir)
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Failed to read {} artifacts directory",
|
||||
artifacts_dir.display()
|
||||
)
|
||||
})?
|
||||
.filter_map(Result::ok)
|
||||
.filter(|e| e.path().extension().is_some_and(|ext| ext == "bin"))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if bins.is_empty() {
|
||||
bail!("No .bin files found in {}", artifacts_dir.display());
|
||||
}
|
||||
|
||||
fs::create_dir_all(&mod_dir)
|
||||
.with_context(|| format!("Failed to create directory {}", mod_dir.display()))?;
|
||||
let mut src = String::new();
|
||||
for entry in bins {
|
||||
let path = entry.path();
|
||||
let name = path.file_stem().unwrap().to_string_lossy();
|
||||
let bytecode =
|
||||
fs::read(&path).with_context(|| format!("Failed to read {}", path.display()))?;
|
||||
let image_id: [u32; 8] = risc0_binfmt::compute_image_id(&bytecode)
|
||||
.with_context(|| format!("Failed to compute image ID for {}", path.display()))?
|
||||
.into();
|
||||
write!(
|
||||
src,
|
||||
"pub const {}_ELF: &[u8] = include_bytes!(r#\"{}\"#);\n\
|
||||
#[expect(clippy::unreadable_literal, reason = \"Generated image IDs from risc0 are cryptographic hashes represented as u32 arrays\")]\n\
|
||||
pub const {}_ID: [u32; 8] = {:?};\n",
|
||||
name.to_uppercase(),
|
||||
path.display(),
|
||||
name.to_uppercase(),
|
||||
image_id
|
||||
)?;
|
||||
}
|
||||
fs::write(&mod_file, src).with_context(|| format!("Failed to write {}", mod_file.display()))?;
|
||||
println!("cargo:warning=Generated module at {}", mod_file.display());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -46,7 +46,7 @@ export EXAMPLE_PROGRAMS_BUILD_DIR=$(pwd)/target/riscv32im-risc0-zkvm-elf/docker
|
||||
> [!IMPORTANT]
|
||||
> **All remaining commands must be run from the `examples/program_deployment` directory.**
|
||||
|
||||
# 3. Hello world example
|
||||
# 3. Hello world example
|
||||
|
||||
The Hello world program reads an arbitrary sequence of bytes from its instruction and appends them to the data field of the input account.
|
||||
Execution succeeds only if the account is:
|
||||
@ -211,7 +211,7 @@ This is the account that the program will claim and write data into.
|
||||
### 3. Loading the program bytecode
|
||||
```rust
|
||||
let bytecode: Vec<u8> = std::fs::read(program_path).unwrap();
|
||||
let program = Program::new(bytecode).unwrap();
|
||||
let program = Program::new(bytecode.into()).unwrap();
|
||||
```
|
||||
The Risc0 ELF is read from disk and wrapped in a Program object, which can be used to compute the program ID. The ID is used by the node to identify which program is invoked by the transaction.
|
||||
|
||||
@ -266,7 +266,7 @@ The relevant part for this tutorial is the account id `7EDHyxejuynBpmbLuiEym9HMU
|
||||
> [!NOTE]
|
||||
> As with public accounts, you can use the `--label` option to assign a label: `wallet account new private --label "my-private-account"`.
|
||||
|
||||
You can check it's uninitialized with
|
||||
You can check it's uninitialized with
|
||||
|
||||
```bash
|
||||
wallet account get --account-id Private/7EDHyxejuynBpmbLuiEym9HMUyCYxZDuF8X3B89ADeMr
|
||||
@ -452,7 +452,7 @@ Because these operations may involve multiple accounts, we'll see how public and
|
||||
> See `methods/guest/src/bin/hello_world_with_move_function.rs`. The program just reads the instruction bytes and updates the accounts state.
|
||||
> All privacy handling happens on the runner side. When constructing the transaction, the runner decides which accounts are public or private and prepares the appropriate proofs. The program itself can't differentiate between privacy modes.
|
||||
|
||||
Let's start by deploying the program
|
||||
Let's start by deploying the program
|
||||
```bash
|
||||
wallet deploy-program $EXAMPLE_PROGRAMS_BUILD_DIR/hello_world_with_move_function.bin
|
||||
```
|
||||
@ -486,7 +486,7 @@ Output:
|
||||
Generated new account with account_id Private/8vzkK7vsdrS2gdPhLk72La8X4FJkgJ5kJLUBRbEVkReU at path /1
|
||||
```
|
||||
|
||||
Let's execute the write function
|
||||
Let's execute the write function
|
||||
|
||||
```bash
|
||||
cargo run --bin run_hello_world_with_move_function \
|
||||
|
||||
@ -43,7 +43,7 @@ async fn main() {
|
||||
|
||||
// Load the program
|
||||
let bytecode: Vec<u8> = std::fs::read(program_path).unwrap();
|
||||
let program = Program::new(bytecode).unwrap();
|
||||
let program = Program::new(bytecode.into()).unwrap();
|
||||
|
||||
// Define the desired greeting in ASCII
|
||||
let greeting: Vec<u8> = vec![72, 111, 108, 97, 32, 109, 117, 110, 100, 111, 33];
|
||||
|
||||
@ -39,7 +39,7 @@ async fn main() {
|
||||
|
||||
// Load the program
|
||||
let bytecode: Vec<u8> = std::fs::read(program_path).unwrap();
|
||||
let program = Program::new(bytecode).unwrap();
|
||||
let program = Program::new(bytecode.into()).unwrap();
|
||||
|
||||
// Define the desired greeting in ASCII
|
||||
let greeting: Vec<u8> = vec![72, 111, 108, 97, 32, 109, 117, 110, 100, 111, 33];
|
||||
|
||||
@ -43,7 +43,7 @@ async fn main() {
|
||||
|
||||
// Load the program
|
||||
let bytecode: Vec<u8> = std::fs::read(program_path).unwrap();
|
||||
let program = Program::new(bytecode).unwrap();
|
||||
let program = Program::new(bytecode.into()).unwrap();
|
||||
|
||||
let instruction_data = ();
|
||||
let nonces = vec![];
|
||||
|
||||
@ -44,9 +44,9 @@ async fn main() {
|
||||
|
||||
// Load the program and its dependencies (the hellow world program)
|
||||
let simple_tail_call_bytecode: Vec<u8> = std::fs::read(simple_tail_call_path).unwrap();
|
||||
let simple_tail_call = Program::new(simple_tail_call_bytecode).unwrap();
|
||||
let simple_tail_call = Program::new(simple_tail_call_bytecode.into()).unwrap();
|
||||
let hello_world_bytecode: Vec<u8> = std::fs::read(hello_world_path).unwrap();
|
||||
let hello_world = Program::new(hello_world_bytecode).unwrap();
|
||||
let hello_world = Program::new(hello_world_bytecode.into()).unwrap();
|
||||
let dependencies: HashMap<ProgramId, Program> =
|
||||
std::iter::once((hello_world.id(), hello_world)).collect();
|
||||
let program_with_dependencies = ProgramWithDependencies::new(simple_tail_call, dependencies);
|
||||
|
||||
@ -45,7 +45,7 @@ async fn main() {
|
||||
|
||||
// Load the program
|
||||
let bytecode: Vec<u8> = std::fs::read(program_path).unwrap();
|
||||
let program = Program::new(bytecode).unwrap();
|
||||
let program = Program::new(bytecode.into()).unwrap();
|
||||
|
||||
// Load signing keys to provide authorization
|
||||
let signing_key = wallet_core
|
||||
|
||||
@ -43,7 +43,7 @@ async fn main() {
|
||||
|
||||
// Load the program
|
||||
let bytecode: Vec<u8> = std::fs::read(program_path).unwrap();
|
||||
let program = Program::new(bytecode).unwrap();
|
||||
let program = Program::new(bytecode.into()).unwrap();
|
||||
|
||||
// Compute the PDA to pass it as input account to the public execution
|
||||
let pda = AccountId::for_public_pda(&program.id(), &PDA_SEED);
|
||||
|
||||
@ -63,7 +63,7 @@ async fn main() {
|
||||
|
||||
// Load the program
|
||||
let bytecode: Vec<u8> = std::fs::read(cli.program_path).unwrap();
|
||||
let program = Program::new(bytecode).unwrap();
|
||||
let program = Program::new(bytecode.into()).unwrap();
|
||||
|
||||
// Initialize wallet
|
||||
let wallet_core = WalletCore::from_env().unwrap();
|
||||
|
||||
@ -9,7 +9,6 @@ workspace = true
|
||||
|
||||
[dependencies]
|
||||
test_fixtures.workspace = true
|
||||
|
||||
lee_core = { workspace = true, features = ["host"] }
|
||||
lee.workspace = true
|
||||
authenticated_transfer_core.workspace = true
|
||||
@ -19,7 +18,7 @@ common.workspace = true
|
||||
key_protocol.workspace = true
|
||||
serde_json.workspace = true
|
||||
token_core.workspace = true
|
||||
ata_core.workspace = true
|
||||
associated_token_account_core.workspace = true
|
||||
vault_core.workspace = true
|
||||
faucet_core.workspace = true
|
||||
bridge_core.workspace = true
|
||||
@ -28,6 +27,9 @@ sequencer_service_rpc = { workspace = true, features = ["client"] }
|
||||
wallet-ffi.workspace = true
|
||||
indexer_ffi.workspace = true
|
||||
indexer_service_protocol.workspace = true
|
||||
system_accounts.workspace = true
|
||||
programs.workspace = true
|
||||
test_programs.workspace = true
|
||||
|
||||
logos-blockchain-http-api-common.workspace = true
|
||||
logos-blockchain-core.workspace = true
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
use anyhow::{Context as _, Result};
|
||||
use integration_tests::{TestContext, private_mention};
|
||||
use key_protocol::key_management::KeyChain;
|
||||
use lee::{Data, program::Program};
|
||||
use lee::Data;
|
||||
use lee_core::account::Nonce;
|
||||
use log::info;
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
@ -31,7 +31,7 @@ async fn get_existing_account() -> Result<()> {
|
||||
|
||||
assert_eq!(
|
||||
account.program_owner,
|
||||
Program::authenticated_transfer_program().id()
|
||||
programs::authenticated_transfer().id()
|
||||
);
|
||||
assert_eq!(account.balance, 10000);
|
||||
assert!(account.data.is_empty());
|
||||
@ -158,7 +158,7 @@ async fn import_private_account() -> Result<()> {
|
||||
let key_chain = KeyChain::new_os_random();
|
||||
let account_id = lee::AccountId::from((&key_chain.nullifier_public_key, 0));
|
||||
let account = lee::Account {
|
||||
program_owner: Program::authenticated_transfer_program().id(),
|
||||
program_owner: programs::authenticated_transfer().id(),
|
||||
balance: 777,
|
||||
data: Data::default(),
|
||||
nonce: Nonce::default(),
|
||||
@ -218,7 +218,7 @@ async fn import_private_account_second_time_overrides_account_data() -> Result<(
|
||||
serde_json::to_string(&key_chain).context("Failed to serialize key chain")?;
|
||||
|
||||
let initial_account = lee::Account {
|
||||
program_owner: Program::authenticated_transfer_program().id(),
|
||||
program_owner: programs::authenticated_transfer().id(),
|
||||
balance: 100,
|
||||
data: Data::default(),
|
||||
nonce: Nonce::default(),
|
||||
@ -237,7 +237,7 @@ async fn import_private_account_second_time_overrides_account_data() -> Result<(
|
||||
.await?;
|
||||
|
||||
let updated_account = lee::Account {
|
||||
program_owner: Program::authenticated_transfer_program().id(),
|
||||
program_owner: programs::authenticated_transfer().id(),
|
||||
balance: 999,
|
||||
data: Data::default(),
|
||||
nonce: Nonce::default(),
|
||||
|
||||
@ -7,12 +7,11 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{Context as _, Result};
|
||||
use ata_core::{compute_ata_seed, get_associated_token_account_id};
|
||||
use associated_token_account_core::{compute_ata_seed, get_associated_token_account_id};
|
||||
use integration_tests::{
|
||||
TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, private_mention, public_mention,
|
||||
verify_commitment_is_in_state,
|
||||
};
|
||||
use lee::program::Program;
|
||||
use log::info;
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
use token_core::{TokenDefinition, TokenHolding};
|
||||
@ -93,7 +92,7 @@ async fn create_ata_initializes_holding_account() -> Result<()> {
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
// Derive expected ATA address and check on-chain state
|
||||
let ata_program_id = Program::ata().id();
|
||||
let ata_program_id = programs::ata().id();
|
||||
let ata_id = get_associated_token_account_id(
|
||||
&ata_program_id,
|
||||
&compute_ata_seed(owner_account_id, definition_account_id),
|
||||
@ -105,7 +104,7 @@ async fn create_ata_initializes_holding_account() -> Result<()> {
|
||||
.await
|
||||
.context("ATA account not found")?;
|
||||
|
||||
assert_eq!(ata_acc.program_owner, Program::token().id());
|
||||
assert_eq!(ata_acc.program_owner, programs::token().id());
|
||||
let holding = TokenHolding::try_from(&ata_acc.data)?;
|
||||
assert_eq!(
|
||||
holding,
|
||||
@ -168,7 +167,7 @@ async fn create_ata_is_idempotent() -> Result<()> {
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
// State must be unchanged
|
||||
let ata_program_id = Program::ata().id();
|
||||
let ata_program_id = programs::ata().id();
|
||||
let ata_id = get_associated_token_account_id(
|
||||
&ata_program_id,
|
||||
&compute_ata_seed(owner_account_id, definition_account_id),
|
||||
@ -180,7 +179,7 @@ async fn create_ata_is_idempotent() -> Result<()> {
|
||||
.await
|
||||
.context("ATA account not found")?;
|
||||
|
||||
assert_eq!(ata_acc.program_owner, Program::token().id());
|
||||
assert_eq!(ata_acc.program_owner, programs::token().id());
|
||||
let holding = TokenHolding::try_from(&ata_acc.data)?;
|
||||
assert_eq!(
|
||||
holding,
|
||||
@ -220,7 +219,7 @@ async fn transfer_and_burn_via_ata() -> Result<()> {
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
// Derive ATA addresses
|
||||
let ata_program_id = Program::ata().id();
|
||||
let ata_program_id = programs::ata().id();
|
||||
let sender_ata_id = get_associated_token_account_id(
|
||||
&ata_program_id,
|
||||
&compute_ata_seed(sender_account_id, definition_account_id),
|
||||
@ -389,7 +388,7 @@ async fn create_ata_with_private_owner() -> Result<()> {
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
// Derive expected ATA address and check on-chain state
|
||||
let ata_program_id = Program::ata().id();
|
||||
let ata_program_id = programs::ata().id();
|
||||
let ata_id = get_associated_token_account_id(
|
||||
&ata_program_id,
|
||||
&compute_ata_seed(owner_account_id, definition_account_id),
|
||||
@ -401,7 +400,7 @@ async fn create_ata_with_private_owner() -> Result<()> {
|
||||
.await
|
||||
.context("ATA account not found")?;
|
||||
|
||||
assert_eq!(ata_acc.program_owner, Program::token().id());
|
||||
assert_eq!(ata_acc.program_owner, programs::token().id());
|
||||
let holding = TokenHolding::try_from(&ata_acc.data)?;
|
||||
assert_eq!(
|
||||
holding,
|
||||
@ -448,7 +447,7 @@ async fn transfer_via_ata_private_owner() -> Result<()> {
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
// Derive ATA addresses
|
||||
let ata_program_id = Program::ata().id();
|
||||
let ata_program_id = programs::ata().id();
|
||||
let sender_ata_id = get_associated_token_account_id(
|
||||
&ata_program_id,
|
||||
&compute_ata_seed(sender_account_id, definition_account_id),
|
||||
@ -572,7 +571,7 @@ async fn burn_via_ata_private_owner() -> Result<()> {
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
// Derive holder's ATA address
|
||||
let ata_program_id = Program::ata().id();
|
||||
let ata_program_id = programs::ata().id();
|
||||
let holder_ata_id = get_associated_token_account_id(
|
||||
&ata_program_id,
|
||||
&compute_ata_seed(holder_account_id, definition_account_id),
|
||||
|
||||
@ -429,7 +429,7 @@ async fn initialize_private_account() -> Result<()> {
|
||||
|
||||
assert_eq!(
|
||||
account.program_owner,
|
||||
Program::authenticated_transfer_program().id()
|
||||
programs::authenticated_transfer().id()
|
||||
);
|
||||
assert_eq!(account.balance, 0);
|
||||
assert!(account.data.is_empty());
|
||||
@ -526,7 +526,7 @@ async fn initialize_private_account_using_label() -> Result<()> {
|
||||
|
||||
assert_eq!(
|
||||
account.program_owner,
|
||||
Program::authenticated_transfer_program().id()
|
||||
programs::authenticated_transfer().id()
|
||||
);
|
||||
|
||||
info!("Successfully initialized private account using label");
|
||||
@ -646,23 +646,20 @@ async fn shielded_transfers_to_two_identifiers_same_npk() -> Result<()> {
|
||||
async fn ppt_cant_chain_call_faucet() -> Result<()> {
|
||||
let ctx = TestContext::new().await?;
|
||||
|
||||
let binary = std::fs::read(
|
||||
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../artifacts/test_program_methods/faucet_chain_caller.bin"),
|
||||
)?;
|
||||
let faucet_chain_caller = test_programs::faucet_chain_caller();
|
||||
let deploy_tx = LeeTransaction::ProgramDeployment(lee::ProgramDeploymentTransaction::new(
|
||||
lee::program_deployment_transaction::Message::new(binary.clone()),
|
||||
lee::program_deployment_transaction::Message::new(faucet_chain_caller.elf().to_owned()),
|
||||
));
|
||||
ctx.sequencer_client().send_transaction(deploy_tx).await?;
|
||||
|
||||
info!("Waiting for deploy block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let faucet_account_id = lee::system_faucet_account_id();
|
||||
let faucet_account_id = system_accounts::faucet_account_id();
|
||||
let attacker_id = ctx.existing_public_accounts()[0];
|
||||
let faucet_program_id = Program::faucet().id();
|
||||
let vault_program_id = Program::vault().id();
|
||||
let auth_transfer_program_id = Program::authenticated_transfer_program().id();
|
||||
let faucet_program_id = programs::faucet().id();
|
||||
let vault_program_id = programs::vault().id();
|
||||
let auth_transfer_program_id = programs::authenticated_transfer().id();
|
||||
let nsk: lee_core::NullifierSecretKey = [3; 32];
|
||||
let npk = NullifierPublicKey::from(&nsk);
|
||||
let vpk = ViewingPublicKey::from_bytes(vec![4_u8; 1184]).unwrap();
|
||||
@ -689,16 +686,12 @@ async fn ppt_cant_chain_call_faucet() -> Result<()> {
|
||||
attacker_vault_id,
|
||||
);
|
||||
|
||||
let faucet_chain_caller = Program::new(binary)?;
|
||||
let program_with_deps = ProgramWithDependencies::new(
|
||||
faucet_chain_caller,
|
||||
[
|
||||
(faucet_program_id, Program::faucet()),
|
||||
(vault_program_id, Program::vault()),
|
||||
(
|
||||
auth_transfer_program_id,
|
||||
Program::authenticated_transfer_program(),
|
||||
),
|
||||
(faucet_program_id, programs::faucet()),
|
||||
(vault_program_id, programs::vault()),
|
||||
(auth_transfer_program_id, programs::authenticated_transfer()),
|
||||
]
|
||||
.into(),
|
||||
);
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
use std::{path::PathBuf, time::Duration};
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Result;
|
||||
use common::transaction::LeeTransaction;
|
||||
use integration_tests::{TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, public_mention};
|
||||
use lee::{program::Program, public_transaction, system_faucet_account_id};
|
||||
use lee::public_transaction;
|
||||
use log::info;
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
use tokio::test;
|
||||
@ -250,7 +250,7 @@ async fn initialize_public_account() -> Result<()> {
|
||||
|
||||
assert_eq!(
|
||||
account.program_owner,
|
||||
Program::authenticated_transfer_program().id()
|
||||
programs::authenticated_transfer().id()
|
||||
);
|
||||
assert_eq!(account.balance, 0);
|
||||
assert_eq!(account.nonce.0, 1);
|
||||
@ -356,7 +356,7 @@ async fn successful_transfer_using_to_label() -> Result<()> {
|
||||
#[test]
|
||||
async fn cannot_transfer_funds_from_system_faucet_account() -> Result<()> {
|
||||
let ctx = TestContext::new().await?;
|
||||
let faucet_account_id = system_faucet_account_id();
|
||||
let faucet_account_id = system_accounts::faucet_account_id();
|
||||
|
||||
let recipient = ctx.existing_public_accounts()[0];
|
||||
let recipient_balance_before = ctx
|
||||
@ -370,7 +370,7 @@ async fn cannot_transfer_funds_from_system_faucet_account() -> Result<()> {
|
||||
|
||||
let amount = 1_u128;
|
||||
let message = public_transaction::Message::try_new(
|
||||
Program::authenticated_transfer_program().id(),
|
||||
programs::authenticated_transfer().id(),
|
||||
vec![faucet_account_id, recipient],
|
||||
vec![],
|
||||
authenticated_transfer_core::Instruction::Transfer { amount },
|
||||
@ -407,10 +407,10 @@ async fn cannot_transfer_funds_from_system_faucet_account() -> Result<()> {
|
||||
#[test]
|
||||
async fn cannot_execute_faucet_program() -> Result<()> {
|
||||
let ctx = TestContext::new().await?;
|
||||
let faucet_account_id = system_faucet_account_id();
|
||||
let faucet_account_id = system_accounts::faucet_account_id();
|
||||
|
||||
let recipient = ctx.existing_public_accounts()[0];
|
||||
let vault_program_id = Program::vault().id();
|
||||
let vault_program_id = programs::vault().id();
|
||||
let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id, recipient);
|
||||
|
||||
let recipient_balance_before = ctx
|
||||
@ -424,7 +424,7 @@ async fn cannot_execute_faucet_program() -> Result<()> {
|
||||
|
||||
let amount = 1_u128;
|
||||
let message = public_transaction::Message::try_new(
|
||||
Program::faucet().id(),
|
||||
programs::faucet().id(),
|
||||
vec![faucet_account_id, recipient_vault_id],
|
||||
vec![],
|
||||
faucet_core::Instruction::GenesisTransferVault {
|
||||
@ -466,28 +466,24 @@ async fn cannot_execute_faucet_program() -> Result<()> {
|
||||
async fn user_tx_that_chain_calls_faucet_is_dropped() -> Result<()> {
|
||||
let ctx = TestContext::new().await?;
|
||||
|
||||
let binary = std::fs::read(
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../artifacts/test_program_methods/faucet_chain_caller.bin"),
|
||||
)?;
|
||||
let faucet_chain_caller_id = Program::new(binary.clone())?.id();
|
||||
let faucet_chain_caller = test_programs::faucet_chain_caller();
|
||||
let deploy_tx = LeeTransaction::ProgramDeployment(lee::ProgramDeploymentTransaction::new(
|
||||
lee::program_deployment_transaction::Message::new(binary),
|
||||
lee::program_deployment_transaction::Message::new(faucet_chain_caller.elf().to_owned()),
|
||||
));
|
||||
ctx.sequencer_client().send_transaction(deploy_tx).await?;
|
||||
|
||||
info!("Waiting for deploy block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let faucet_account_id = system_faucet_account_id();
|
||||
let faucet_account_id = system_accounts::faucet_account_id();
|
||||
let attacker = ctx.existing_public_accounts()[0];
|
||||
let faucet_program_id = Program::faucet().id();
|
||||
let vault_program_id = Program::vault().id();
|
||||
let faucet_program_id = programs::faucet().id();
|
||||
let vault_program_id = programs::vault().id();
|
||||
let attacker_vault_id = vault_core::compute_vault_account_id(vault_program_id, attacker);
|
||||
let amount: u128 = 1;
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
faucet_chain_caller_id,
|
||||
faucet_chain_caller.id(),
|
||||
vec![faucet_account_id, attacker_vault_id],
|
||||
vec![],
|
||||
(faucet_program_id, vault_program_id, attacker, amount),
|
||||
|
||||
@ -94,16 +94,12 @@ async fn accept_transaction_within_limit() -> Result<()> {
|
||||
|
||||
#[test]
|
||||
async fn transaction_deferred_to_next_block_when_current_full() -> Result<()> {
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let artifacts_dir =
|
||||
std::path::PathBuf::from(manifest_dir).join("../artifacts/test_program_methods");
|
||||
|
||||
let burner_bytecode = std::fs::read(artifacts_dir.join("burner.bin"))?;
|
||||
let chain_caller_bytecode = std::fs::read(artifacts_dir.join("chain_caller.bin"))?;
|
||||
let claimer = test_programs::claimer();
|
||||
let chain_caller = test_programs::chain_caller();
|
||||
|
||||
// Calculate block size to fit only one of the two transactions, leaving some room for headers
|
||||
// (e.g., 10 KiB)
|
||||
let max_program_size = burner_bytecode.len().max(chain_caller_bytecode.len());
|
||||
let max_program_size = claimer.elf().len().max(chain_caller.elf().len());
|
||||
let block_size = ByteSize::b((max_program_size + 10 * 1024) as u64);
|
||||
|
||||
let ctx = TestContext::builder()
|
||||
@ -116,16 +112,13 @@ async fn transaction_deferred_to_next_block_when_current_full() -> Result<()> {
|
||||
.build()
|
||||
.await?;
|
||||
|
||||
let burner_id = Program::new(burner_bytecode.clone())?.id();
|
||||
let chain_caller_id = Program::new(chain_caller_bytecode.clone())?.id();
|
||||
|
||||
let initial_block_height = ctx.sequencer_client().get_last_block_id().await?;
|
||||
|
||||
// Submit both program deployments
|
||||
ctx.sequencer_client()
|
||||
.send_transaction(LeeTransaction::ProgramDeployment(
|
||||
lee::ProgramDeploymentTransaction::new(
|
||||
lee::program_deployment_transaction::Message::new(burner_bytecode),
|
||||
lee::program_deployment_transaction::Message::new(claimer.elf().to_owned()),
|
||||
),
|
||||
))
|
||||
.await?;
|
||||
@ -133,7 +126,7 @@ async fn transaction_deferred_to_next_block_when_current_full() -> Result<()> {
|
||||
ctx.sequencer_client()
|
||||
.send_transaction(LeeTransaction::ProgramDeployment(
|
||||
lee::ProgramDeploymentTransaction::new(
|
||||
lee::program_deployment_transaction::Message::new(chain_caller_bytecode),
|
||||
lee::program_deployment_transaction::Message::new(chain_caller.elf().to_owned()),
|
||||
),
|
||||
))
|
||||
.await?;
|
||||
@ -156,7 +149,7 @@ async fn transaction_deferred_to_next_block_when_current_full() -> Result<()> {
|
||||
.filter_map(|tx| {
|
||||
if let LeeTransaction::ProgramDeployment(deployment) = tx {
|
||||
let bytecode = deployment.message.clone().into_bytecode();
|
||||
Program::new(bytecode).ok().map(|p| p.id())
|
||||
Program::new(bytecode.into()).ok().map(|p| p.id())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -173,8 +166,9 @@ async fn transaction_deferred_to_next_block_when_current_full() -> Result<()> {
|
||||
"Expected exactly one program deployment in block 1"
|
||||
);
|
||||
assert_eq!(
|
||||
block1_program_ids[0], burner_id,
|
||||
"Expected burner program to be deployed in block 1"
|
||||
block1_program_ids[0],
|
||||
claimer.id(),
|
||||
"Expected claimer program to be deployed in block 1"
|
||||
);
|
||||
|
||||
// Wait for second block
|
||||
@ -194,7 +188,8 @@ async fn transaction_deferred_to_next_block_when_current_full() -> Result<()> {
|
||||
"Expected exactly one program deployment in block 2"
|
||||
);
|
||||
assert_eq!(
|
||||
block2_program_ids[0], chain_caller_id,
|
||||
block2_program_ids[0],
|
||||
chain_caller.id(),
|
||||
"Expected chain_caller program to be deployed in block 2"
|
||||
);
|
||||
|
||||
|
||||
@ -43,12 +43,12 @@ async fn public_bridge_deposit_invocation_is_dropped() -> anyhow::Result<()> {
|
||||
let ctx = TestContext::new().await?;
|
||||
|
||||
let recipient_id = ctx.existing_public_accounts()[0];
|
||||
let bridge_account_id = lee::system_bridge_account_id();
|
||||
let vault_program_id = Program::vault().id();
|
||||
let bridge_account_id = system_accounts::bridge_account_id();
|
||||
let vault_program_id = programs::vault().id();
|
||||
let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id, recipient_id);
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
Program::bridge().id(),
|
||||
programs::bridge().id(),
|
||||
vec![bridge_account_id, recipient_vault_id],
|
||||
vec![],
|
||||
bridge_core::Instruction::Deposit {
|
||||
@ -103,8 +103,8 @@ async fn private_bridge_deposit_invocation_is_dropped() -> anyhow::Result<()> {
|
||||
let ctx = TestContext::new().await?;
|
||||
|
||||
let recipient_id = ctx.existing_public_accounts()[0];
|
||||
let bridge_account_id = lee::system_bridge_account_id();
|
||||
let vault_program_id = Program::vault().id();
|
||||
let bridge_account_id = system_accounts::bridge_account_id();
|
||||
let vault_program_id = programs::vault().id();
|
||||
let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id, recipient_id);
|
||||
|
||||
// Get pre-state of bridge and vault accounts
|
||||
@ -126,12 +126,12 @@ async fn private_bridge_deposit_invocation_is_dropped() -> anyhow::Result<()> {
|
||||
// Create program with dependencies
|
||||
let program_with_deps =
|
||||
lee::privacy_preserving_transaction::circuit::ProgramWithDependencies::new(
|
||||
Program::bridge(),
|
||||
programs::bridge(),
|
||||
[
|
||||
(vault_program_id, Program::vault()),
|
||||
(vault_program_id, programs::vault()),
|
||||
(
|
||||
Program::authenticated_transfer_program().id(),
|
||||
Program::authenticated_transfer_program(),
|
||||
programs::authenticated_transfer().id(),
|
||||
programs::authenticated_transfer(),
|
||||
),
|
||||
]
|
||||
.into(),
|
||||
@ -386,7 +386,7 @@ async fn bedrock_deposit_claim_and_withdraw_round_trip_succeeds() -> anyhow::Res
|
||||
let bedrock_account_pk = "2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26";
|
||||
let recipient_id = ctx.existing_public_accounts()[0];
|
||||
let amount = 1_u64;
|
||||
let vault_program_id = Program::vault().id();
|
||||
let vault_program_id = programs::vault().id();
|
||||
let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id, recipient_id);
|
||||
|
||||
let vault_balance_before = ctx
|
||||
@ -474,7 +474,7 @@ async fn bedrock_deposit_claim_and_withdraw_round_trip_succeeds() -> anyhow::Res
|
||||
// state as the sequencer — including the bridge system account the deposit
|
||||
// modifies, which is the case the hot fix unblocks.
|
||||
wait_for_indexer_to_catch_up(&ctx).await?;
|
||||
let bridge_account_id = lee::system_bridge_account_id();
|
||||
let bridge_account_id = system_accounts::bridge_account_id();
|
||||
for account_id in [recipient_id, recipient_vault_id, bridge_account_id] {
|
||||
let indexer_account = indexer_service_rpc::RpcClient::get_account(
|
||||
// `deref` is needed for correct trait resolution
|
||||
|
||||
@ -12,7 +12,7 @@ use integration_tests::{
|
||||
public_mention, verify_commitment_is_in_state,
|
||||
};
|
||||
use key_protocol::key_management::key_tree::chain_index::ChainIndex;
|
||||
use lee::{AccountId, program::Program};
|
||||
use lee::AccountId;
|
||||
use log::info;
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
use tokio::test;
|
||||
@ -257,11 +257,11 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
|
||||
assert_eq!(
|
||||
acc1.account.program_owner,
|
||||
Program::authenticated_transfer_program().id()
|
||||
programs::authenticated_transfer().id()
|
||||
);
|
||||
assert_eq!(
|
||||
acc2.account.program_owner,
|
||||
Program::authenticated_transfer_program().id()
|
||||
programs::authenticated_transfer().id()
|
||||
);
|
||||
|
||||
assert_eq!(acc1.account.balance, 100);
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{Context as _, Result};
|
||||
use common::PINATA_BASE58;
|
||||
use integration_tests::{
|
||||
TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, private_mention, public_mention,
|
||||
verify_commitment_is_in_state,
|
||||
@ -44,7 +43,7 @@ async fn claim_pinata_to_uninitialized_public_account_fails_fast() -> Result<()>
|
||||
|
||||
let pinata_balance_pre = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(PINATA_BASE58.parse().unwrap())
|
||||
.get_account_balance(system_accounts::pinata_account_id())
|
||||
.await?;
|
||||
|
||||
let claim_result = wallet::cli::execute_subcommand(
|
||||
@ -67,7 +66,7 @@ async fn claim_pinata_to_uninitialized_public_account_fails_fast() -> Result<()>
|
||||
|
||||
let pinata_balance_post = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(PINATA_BASE58.parse().unwrap())
|
||||
.get_account_balance(system_accounts::pinata_account_id())
|
||||
.await?;
|
||||
|
||||
assert_eq!(pinata_balance_post, pinata_balance_pre);
|
||||
@ -96,7 +95,7 @@ async fn claim_pinata_to_uninitialized_private_account_fails_fast() -> Result<()
|
||||
|
||||
let pinata_balance_pre = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(PINATA_BASE58.parse().unwrap())
|
||||
.get_account_balance(system_accounts::pinata_account_id())
|
||||
.await?;
|
||||
|
||||
let claim_result = wallet::cli::execute_subcommand(
|
||||
@ -119,7 +118,7 @@ async fn claim_pinata_to_uninitialized_private_account_fails_fast() -> Result<()
|
||||
|
||||
let pinata_balance_post = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(PINATA_BASE58.parse().unwrap())
|
||||
.get_account_balance(system_accounts::pinata_account_id())
|
||||
.await?;
|
||||
|
||||
assert_eq!(pinata_balance_post, pinata_balance_pre);
|
||||
@ -138,7 +137,7 @@ async fn claim_pinata_to_existing_public_account() -> Result<()> {
|
||||
|
||||
let pinata_balance_pre = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(PINATA_BASE58.parse().unwrap())
|
||||
.get_account_balance(system_accounts::pinata_account_id())
|
||||
.await?;
|
||||
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
@ -149,7 +148,7 @@ async fn claim_pinata_to_existing_public_account() -> Result<()> {
|
||||
info!("Checking correct balance move");
|
||||
let pinata_balance_post = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(PINATA_BASE58.parse().unwrap())
|
||||
.get_account_balance(system_accounts::pinata_account_id())
|
||||
.await?;
|
||||
|
||||
let winner_balance_post = ctx
|
||||
@ -176,7 +175,7 @@ async fn claim_pinata_to_existing_private_account() -> Result<()> {
|
||||
|
||||
let pinata_balance_pre = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(PINATA_BASE58.parse().unwrap())
|
||||
.get_account_balance(system_accounts::pinata_account_id())
|
||||
.await?;
|
||||
|
||||
let result = wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
@ -199,7 +198,7 @@ async fn claim_pinata_to_existing_private_account() -> Result<()> {
|
||||
|
||||
let pinata_balance_post = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(PINATA_BASE58.parse().unwrap())
|
||||
.get_account_balance(system_accounts::pinata_account_id())
|
||||
.await?;
|
||||
|
||||
assert_eq!(pinata_balance_post, pinata_balance_pre - pinata_prize);
|
||||
@ -253,7 +252,7 @@ async fn claim_pinata_to_new_private_account() -> Result<()> {
|
||||
|
||||
let pinata_balance_pre = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(PINATA_BASE58.parse().unwrap())
|
||||
.get_account_balance(system_accounts::pinata_account_id())
|
||||
.await?;
|
||||
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
@ -269,7 +268,7 @@ async fn claim_pinata_to_new_private_account() -> Result<()> {
|
||||
|
||||
let pinata_balance_post = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(PINATA_BASE58.parse().unwrap())
|
||||
.get_account_balance(system_accounts::pinata_account_id())
|
||||
.await?;
|
||||
|
||||
assert_eq!(pinata_balance_post, pinata_balance_pre - pinata_prize);
|
||||
|
||||
@ -3,14 +3,13 @@
|
||||
reason = "We don't care about these in tests"
|
||||
)]
|
||||
|
||||
use std::{path::PathBuf, time::Duration};
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{Context as _, Result};
|
||||
use authenticated_transfer_core::Instruction as AuthTransferInstruction;
|
||||
use common::transaction::LeeTransaction;
|
||||
use integration_tests::{
|
||||
LEE_PROGRAM_FOR_TEST_PDA_SPEND_PROXY, TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext,
|
||||
verify_commitment_is_in_state,
|
||||
TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, verify_commitment_is_in_state,
|
||||
};
|
||||
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
|
||||
use lee::{
|
||||
@ -165,14 +164,8 @@ async fn private_pda_family_members_receive_and_spend() -> Result<()> {
|
||||
(kc.nullifier_public_key, kc.viewing_public_key.clone())
|
||||
};
|
||||
|
||||
let proxy = {
|
||||
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../artifacts/test_program_methods")
|
||||
.join(LEE_PROGRAM_FOR_TEST_PDA_SPEND_PROXY);
|
||||
Program::new(std::fs::read(&path).with_context(|| format!("reading {path:?}"))?)
|
||||
.context("invalid pda_spend_proxy binary")?
|
||||
};
|
||||
let auth_transfer = Program::authenticated_transfer_program();
|
||||
let proxy = test_programs::pda_spend_proxy();
|
||||
let auth_transfer = programs::authenticated_transfer();
|
||||
let proxy_id = proxy.id();
|
||||
let auth_transfer_id = auth_transfer.id();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
|
||||
@ -3,14 +3,11 @@
|
||||
reason = "We don't care about these in tests"
|
||||
)]
|
||||
|
||||
use std::{path::PathBuf, time::Duration};
|
||||
use std::{io::Write as _, time::Duration};
|
||||
|
||||
use anyhow::Result;
|
||||
use common::transaction::LeeTransaction;
|
||||
use integration_tests::{
|
||||
LEE_PROGRAM_FOR_TEST_DATA_CHANGER, TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext,
|
||||
};
|
||||
use lee::program::Program;
|
||||
use integration_tests::{TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext};
|
||||
use log::info;
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
use tokio::test;
|
||||
@ -23,10 +20,11 @@ use wallet::cli::{
|
||||
async fn deploy_and_execute_program() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let binary_filepath: PathBuf = PathBuf::from(manifest_dir)
|
||||
.join("../artifacts/test_program_methods")
|
||||
.join(LEE_PROGRAM_FOR_TEST_DATA_CHANGER);
|
||||
let claimer = test_programs::claimer();
|
||||
let mut tempfile = tempfile::NamedTempFile::new()?;
|
||||
tempfile.write_all(claimer.elf())?;
|
||||
|
||||
let binary_filepath = tempfile.path().to_owned();
|
||||
|
||||
let command = Command::DeployProgram {
|
||||
binary_filepath: binary_filepath.clone(),
|
||||
@ -37,13 +35,6 @@ async fn deploy_and_execute_program() -> Result<()> {
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
// The program is the data changer and takes one account as input.
|
||||
// We pass an uninitialized account and we expect after execution to be owned by the data
|
||||
// changer program (LEE account claiming mechanism) with data equal to [0] (due to program
|
||||
// logic)
|
||||
let bytecode = std::fs::read(binary_filepath)?;
|
||||
let data_changer = Program::new(bytecode)?;
|
||||
|
||||
let SubcommandReturnValue::RegisterAccount { account_id } = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
@ -61,12 +52,8 @@ async fn deploy_and_execute_program() -> Result<()> {
|
||||
.wallet()
|
||||
.get_account_public_signing_key(account_id)
|
||||
.unwrap();
|
||||
let message = lee::public_transaction::Message::try_new(
|
||||
data_changer.id(),
|
||||
vec![account_id],
|
||||
nonces,
|
||||
vec![0],
|
||||
)?;
|
||||
let message =
|
||||
lee::public_transaction::Message::try_new(claimer.id(), vec![account_id], nonces, ())?;
|
||||
let witness_set = lee::public_transaction::WitnessSet::for_message(&message, &[private_key]);
|
||||
let transaction = lee::PublicTransaction::new(message, witness_set);
|
||||
let _response = ctx
|
||||
@ -81,7 +68,7 @@ async fn deploy_and_execute_program() -> Result<()> {
|
||||
|
||||
let post_state_account = ctx.sequencer_client().get_account(account_id).await?;
|
||||
|
||||
assert_eq!(post_state_account.program_owner, data_changer.id());
|
||||
assert_eq!(post_state_account.program_owner, claimer.id());
|
||||
assert_eq!(post_state_account.balance, 0);
|
||||
assert_eq!(post_state_account.data.as_ref(), &[0]);
|
||||
assert_eq!(post_state_account.nonce.0, 1);
|
||||
|
||||
@ -12,7 +12,6 @@ use integration_tests::{
|
||||
verify_commitment_is_in_state,
|
||||
};
|
||||
use key_protocol::key_management::key_tree::chain_index::ChainIndex;
|
||||
use lee::program::Program;
|
||||
use log::info;
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
use token_core::{TokenDefinition, TokenHolding};
|
||||
@ -99,7 +98,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
|
||||
.await?;
|
||||
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
|
||||
|
||||
assert_eq!(definition_acc.program_owner, Program::token().id());
|
||||
assert_eq!(definition_acc.program_owner, programs::token().id());
|
||||
assert_eq!(
|
||||
token_definition,
|
||||
TokenDefinition::Fungible {
|
||||
@ -116,7 +115,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
|
||||
.await?;
|
||||
|
||||
// The account must be owned by the token program
|
||||
assert_eq!(supply_acc.program_owner, Program::token().id());
|
||||
assert_eq!(supply_acc.program_owner, programs::token().id());
|
||||
let token_holding = TokenHolding::try_from(&supply_acc.data)?;
|
||||
assert_eq!(
|
||||
token_holding,
|
||||
@ -148,7 +147,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
|
||||
.sequencer_client()
|
||||
.get_account(supply_account_id)
|
||||
.await?;
|
||||
assert_eq!(supply_acc.program_owner, Program::token().id());
|
||||
assert_eq!(supply_acc.program_owner, programs::token().id());
|
||||
let token_holding = TokenHolding::try_from(&supply_acc.data)?;
|
||||
assert_eq!(
|
||||
token_holding,
|
||||
@ -163,7 +162,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
|
||||
.sequencer_client()
|
||||
.get_account(recipient_account_id)
|
||||
.await?;
|
||||
assert_eq!(recipient_acc.program_owner, Program::token().id());
|
||||
assert_eq!(recipient_acc.program_owner, programs::token().id());
|
||||
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
|
||||
assert_eq!(
|
||||
token_holding,
|
||||
@ -344,7 +343,7 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
|
||||
.await?;
|
||||
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
|
||||
|
||||
assert_eq!(definition_acc.program_owner, Program::token().id());
|
||||
assert_eq!(definition_acc.program_owner, programs::token().id());
|
||||
assert_eq!(
|
||||
token_definition,
|
||||
TokenDefinition::Fungible {
|
||||
@ -508,7 +507,7 @@ async fn create_token_with_private_definition() -> Result<()> {
|
||||
.get_account(supply_account_id)
|
||||
.await?;
|
||||
|
||||
assert_eq!(supply_acc.program_owner, Program::token().id());
|
||||
assert_eq!(supply_acc.program_owner, programs::token().id());
|
||||
let token_holding = TokenHolding::try_from(&supply_acc.data)?;
|
||||
assert_eq!(
|
||||
token_holding,
|
||||
@ -1231,7 +1230,7 @@ async fn create_token_using_labels() -> Result<()> {
|
||||
.await?;
|
||||
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
|
||||
|
||||
assert_eq!(definition_acc.program_owner, Program::token().id());
|
||||
assert_eq!(definition_acc.program_owner, programs::token().id());
|
||||
assert_eq!(
|
||||
token_definition,
|
||||
TokenDefinition::Fungible {
|
||||
|
||||
@ -76,7 +76,7 @@ impl TpsTestManager {
|
||||
&self,
|
||||
sequencer_client: &sequencer_service_rpc::SequencerClient,
|
||||
) -> Result<()> {
|
||||
let vault_program_id = Program::vault().id();
|
||||
let vault_program_id = programs::vault().id();
|
||||
|
||||
let mut tx_hashes = Vec::with_capacity(self.public_keypairs.len());
|
||||
for (private_key, account_id) in &self.public_keypairs {
|
||||
@ -126,7 +126,7 @@ impl TpsTestManager {
|
||||
/// Must be called after `claim_vault_funds`, which sets each account's nonce to 1.
|
||||
pub fn build_public_txs(&self) -> Vec<PublicTransaction> {
|
||||
// Create valid public transactions
|
||||
let program = Program::authenticated_transfer_program();
|
||||
let program = programs::authenticated_transfer();
|
||||
let public_txs: Vec<PublicTransaction> = self
|
||||
.public_keypairs
|
||||
.windows(2)
|
||||
@ -254,7 +254,7 @@ pub async fn tps_test() -> Result<()> {
|
||||
/// multiple times with the purpose of testing the node's processing performance.
|
||||
#[expect(dead_code, reason = "No idea if we need this, should we remove it?")]
|
||||
fn build_privacy_transaction() -> PrivacyPreservingTransaction {
|
||||
let program = Program::authenticated_transfer_program();
|
||||
let program = programs::authenticated_transfer();
|
||||
let sender_nsk = [1; 32];
|
||||
let sender_vpk = ViewingPublicKey::from_seed(&[99_u8; 32], &[100_u8; 32]);
|
||||
let sender_npk = NullifierPublicKey::from(&sender_nsk);
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
|
||||
use anyhow::{Context as _, Result};
|
||||
use integration_tests::{TestContext, private_mention, public_mention};
|
||||
use lee::program::Program;
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
use tokio::test;
|
||||
use wallet::cli::{Command, SubcommandReturnValue, programs::vault::VaultSubcommand};
|
||||
@ -18,7 +17,7 @@ async fn public_transfer_and_public_claim() -> Result<()> {
|
||||
let sender = ctx.existing_public_accounts()[0];
|
||||
let recipient = ctx.existing_public_accounts()[1];
|
||||
|
||||
let vault_program_id = Program::vault().id();
|
||||
let vault_program_id = programs::vault().id();
|
||||
let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id, recipient);
|
||||
|
||||
let sender_balance_before = ctx.sequencer_client().get_account_balance(sender).await?;
|
||||
@ -109,7 +108,7 @@ async fn private_transfer_and_private_claim() -> Result<()> {
|
||||
let sender = ctx.existing_private_accounts()[0];
|
||||
let owner = ctx.existing_private_accounts()[1];
|
||||
|
||||
let vault_program_id = Program::vault().id();
|
||||
let vault_program_id = programs::vault().id();
|
||||
let owner_vault_id = vault_core::compute_vault_account_id(vault_program_id, owner);
|
||||
|
||||
let sender_balance_before = ctx
|
||||
|
||||
@ -608,7 +608,7 @@ fn test_wallet_ffi_get_account_public() -> Result<()> {
|
||||
|
||||
assert_eq!(
|
||||
account.program_owner,
|
||||
Program::authenticated_transfer_program().id()
|
||||
programs::authenticated_transfer().id()
|
||||
);
|
||||
assert_eq!(account.balance, 10000);
|
||||
assert!(account.data.is_empty());
|
||||
@ -648,7 +648,7 @@ fn test_wallet_ffi_get_account_private() -> Result<()> {
|
||||
|
||||
assert_eq!(
|
||||
account.program_owner,
|
||||
Program::authenticated_transfer_program().id()
|
||||
programs::authenticated_transfer().id()
|
||||
);
|
||||
assert_eq!(account.balance, 10000);
|
||||
assert!(account.data.is_empty());
|
||||
@ -846,7 +846,7 @@ fn wallet_ffi_init_public_account_auth_transfer() -> Result<()> {
|
||||
};
|
||||
assert_eq!(
|
||||
account.program_owner,
|
||||
Program::authenticated_transfer_program().id()
|
||||
programs::authenticated_transfer().id()
|
||||
);
|
||||
|
||||
unsafe {
|
||||
@ -906,7 +906,7 @@ fn wallet_ffi_init_private_account_auth_transfer() -> Result<()> {
|
||||
};
|
||||
assert_eq!(
|
||||
account.program_owner,
|
||||
Program::authenticated_transfer_program().id()
|
||||
programs::authenticated_transfer().id()
|
||||
);
|
||||
|
||||
unsafe {
|
||||
@ -1493,7 +1493,7 @@ fn test_wallet_ffi_bridge_withdraw() -> Result<()> {
|
||||
mnemonic: _,
|
||||
} = new_wallet_ffi_with_test_context_config(&ctx, home.path())?;
|
||||
let from: FfiBytes32 = ctx.ctx().existing_public_accounts()[0].into();
|
||||
let bridge_account: FfiBytes32 = lee::system_bridge_account_id().into();
|
||||
let bridge_account: FfiBytes32 = system_accounts::bridge_account_id().into();
|
||||
let bedrock_account_pk = FfiBytes32::from_bytes([0x42; 32]);
|
||||
let amount = 100_u64;
|
||||
|
||||
@ -1585,7 +1585,7 @@ fn test_wallet_ffi_transfer_generic_public() -> Result<()> {
|
||||
let instruction_words_size = instruction_data.len();
|
||||
let instruction_words = Box::into_raw(instruction_data.into_boxed_slice()) as *const u32;
|
||||
|
||||
let program: ProgramWithDependencies = Program::authenticated_transfer_program().into();
|
||||
let program: ProgramWithDependencies = programs::authenticated_transfer().into();
|
||||
let program_with_dependencies: FfiProgramWithDependencies = program.into();
|
||||
|
||||
unsafe {
|
||||
@ -1682,7 +1682,7 @@ fn test_wallet_ffi_transfer_generic_private() -> Result<()> {
|
||||
let instruction_words_size = instruction_data.len();
|
||||
let instruction_words = Box::into_raw(instruction_data.into_boxed_slice()) as *const u32;
|
||||
|
||||
let program: ProgramWithDependencies = Program::authenticated_transfer_program().into();
|
||||
let program: ProgramWithDependencies = programs::authenticated_transfer().into();
|
||||
let program_with_dependencies: FfiProgramWithDependencies = program.into();
|
||||
|
||||
unsafe {
|
||||
|
||||
12
lee/privacy_preserving_circuit/Cargo.toml
Normal file
12
lee/privacy_preserving_circuit/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "privacy_preserving_circuit"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
license = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
lee_core.workspace = true
|
||||
risc0-zkvm.workspace = true
|
||||
@ -9,9 +9,6 @@ workspace = true
|
||||
|
||||
[dependencies]
|
||||
lee_core = { workspace = true, features = ["host"] }
|
||||
clock_core.workspace = true
|
||||
faucet_core.workspace = true
|
||||
bridge_core.workspace = true
|
||||
|
||||
anyhow.workspace = true
|
||||
thiserror.workspace = true
|
||||
@ -27,14 +24,12 @@ risc0-binfmt = "3.0.2"
|
||||
log.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
risc0-build = "3.0.3"
|
||||
risc0-binfmt = "3.0.2"
|
||||
build_utils.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
lee_core = { workspace = true, features = ["test_utils"] }
|
||||
token_core.workspace = true
|
||||
authenticated_transfer_core.workspace = true
|
||||
test_program_methods.workspace = true
|
||||
test_methods = { path = "test_methods" }
|
||||
|
||||
env_logger.workspace = true
|
||||
hex-literal = "1.0.0"
|
||||
|
||||
@ -1,43 +1,5 @@
|
||||
use std::{env, fmt::Write as _, fs, path::PathBuf};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?);
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
|
||||
let mod_dir = out_dir.join("program_methods");
|
||||
let mod_file = mod_dir.join("mod.rs");
|
||||
let program_methods_dir = manifest_dir.join("../../artifacts/program_methods/");
|
||||
|
||||
println!("cargo:rerun-if-changed={}", program_methods_dir.display());
|
||||
|
||||
let bins = fs::read_dir(&program_methods_dir)?
|
||||
.filter_map(Result::ok)
|
||||
.filter(|e| e.path().extension().is_some_and(|ext| ext == "bin"))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if bins.is_empty() {
|
||||
return Err(format!("No .bin files found in {}", program_methods_dir.display()).into());
|
||||
}
|
||||
|
||||
fs::create_dir_all(&mod_dir)?;
|
||||
let mut src = String::new();
|
||||
for entry in bins {
|
||||
let path = entry.path();
|
||||
let name = path.file_stem().unwrap().to_string_lossy();
|
||||
let bytecode = fs::read(&path)?;
|
||||
let image_id: [u32; 8] = risc0_binfmt::compute_image_id(&bytecode)?.into();
|
||||
write!(
|
||||
src,
|
||||
"pub const {}_ELF: &[u8] = include_bytes!(r#\"{}\"#);\n\
|
||||
#[expect(clippy::unreadable_literal, reason = \"Generated image IDs from risc0 are cryptographic hashes represented as u32 arrays\")]\n\
|
||||
pub const {}_ID: [u32; 8] = {:?};\n",
|
||||
name.to_uppercase(),
|
||||
path.display(),
|
||||
name.to_uppercase(),
|
||||
image_id
|
||||
)?;
|
||||
}
|
||||
fs::write(&mod_file, src)?;
|
||||
println!("cargo:warning=Generated module at {}", mod_file.display());
|
||||
build_utils::include_artifacts("lee/privacy_preserving_circuit")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -9,17 +9,16 @@ pub use lee_core::{
|
||||
encryption::EphemeralPublicKey,
|
||||
program::ProgramId,
|
||||
};
|
||||
pub use privacy_preserving_circuit::{
|
||||
PRIVACY_PRESERVING_CIRCUIT_ELF, PRIVACY_PRESERVING_CIRCUIT_ID,
|
||||
};
|
||||
pub use privacy_preserving_transaction::{
|
||||
PrivacyPreservingTransaction, circuit::execute_and_prove,
|
||||
};
|
||||
pub use program_deployment_transaction::ProgramDeploymentTransaction;
|
||||
pub use program_methods::PRIVACY_PRESERVING_CIRCUIT_ID;
|
||||
pub use public_transaction::PublicTransaction;
|
||||
pub use signature::{PrivateKey, PublicKey, Signature};
|
||||
pub use state::{
|
||||
CLOCK_01_PROGRAM_ACCOUNT_ID, CLOCK_10_PROGRAM_ACCOUNT_ID, CLOCK_50_PROGRAM_ACCOUNT_ID,
|
||||
CLOCK_PROGRAM_ACCOUNT_IDS, V03State, system_bridge_account_id, system_faucet_account_id,
|
||||
};
|
||||
pub use state::V03State;
|
||||
pub use validated_state_diff::ValidatedStateDiff;
|
||||
|
||||
pub mod encoding;
|
||||
@ -33,6 +32,238 @@ mod signature;
|
||||
mod state;
|
||||
mod validated_state_diff;
|
||||
|
||||
pub mod program_methods {
|
||||
include!(concat!(env!("OUT_DIR"), "/program_methods/mod.rs"));
|
||||
mod privacy_preserving_circuit {
|
||||
include!(concat!(
|
||||
env!("OUT_DIR"),
|
||||
"/lee/privacy_preserving_circuit/mod.rs"
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_methods {
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::program::Program;
|
||||
|
||||
#[must_use]
|
||||
pub const fn simple_balance_transfer() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::SIMPLE_BALANCE_TRANSFER_ID,
|
||||
Cow::Borrowed(test_methods::SIMPLE_BALANCE_TRANSFER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn nonce_changer() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::NONCE_CHANGER_ID,
|
||||
Cow::Borrowed(test_methods::NONCE_CHANGER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn extra_output() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::EXTRA_OUTPUT_ID,
|
||||
Cow::Borrowed(test_methods::EXTRA_OUTPUT_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn missing_output() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::MISSING_OUTPUT_ID,
|
||||
Cow::Borrowed(test_methods::MISSING_OUTPUT_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn program_owner_changer() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::PROGRAM_OWNER_CHANGER_ID,
|
||||
Cow::Borrowed(test_methods::PROGRAM_OWNER_CHANGER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn data_changer() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::DATA_CHANGER_ID,
|
||||
Cow::Borrowed(test_methods::DATA_CHANGER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn minter() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::MINTER_ID,
|
||||
Cow::Borrowed(test_methods::MINTER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn burner() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::BURNER_ID,
|
||||
Cow::Borrowed(test_methods::BURNER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn auth_asserting_noop() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::AUTH_ASSERTING_NOOP_ID,
|
||||
Cow::Borrowed(test_methods::AUTH_ASSERTING_NOOP_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn private_pda_delegator() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::PRIVATE_PDA_DELEGATOR_ID,
|
||||
Cow::Borrowed(test_methods::PRIVATE_PDA_DELEGATOR_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn pda_claimer() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::PDA_CLAIMER_ID,
|
||||
Cow::Borrowed(test_methods::PDA_CLAIMER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn two_pda_claimer() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::TWO_PDA_CLAIMER_ID,
|
||||
Cow::Borrowed(test_methods::TWO_PDA_CLAIMER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn noop() -> Program {
|
||||
Program::new_unchecked(test_methods::NOOP_ID, Cow::Borrowed(test_methods::NOOP_ELF))
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn chain_caller() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::CHAIN_CALLER_ID,
|
||||
Cow::Borrowed(test_methods::CHAIN_CALLER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn modified_transfer_program() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::MODIFIED_TRANSFER_ID,
|
||||
Cow::Borrowed(test_methods::MODIFIED_TRANSFER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn malicious_authorization_changer() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::MALICIOUS_AUTHORIZATION_CHANGER_ID,
|
||||
Cow::Borrowed(test_methods::MALICIOUS_AUTHORIZATION_CHANGER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn validity_window() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::VALIDITY_WINDOW_ID,
|
||||
Cow::Borrowed(test_methods::VALIDITY_WINDOW_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn flash_swap_initiator() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::FLASH_SWAP_INITIATOR_ID,
|
||||
Cow::Borrowed(test_methods::FLASH_SWAP_INITIATOR_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn flash_swap_callback() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::FLASH_SWAP_CALLBACK_ID,
|
||||
Cow::Borrowed(test_methods::FLASH_SWAP_CALLBACK_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn malicious_self_program_id() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::MALICIOUS_SELF_PROGRAM_ID_ID,
|
||||
Cow::Borrowed(test_methods::MALICIOUS_SELF_PROGRAM_ID_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn malicious_caller_program_id() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::MALICIOUS_CALLER_PROGRAM_ID_ID,
|
||||
Cow::Borrowed(test_methods::MALICIOUS_CALLER_PROGRAM_ID_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn pda_spend_proxy() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::PDA_SPEND_PROXY_ID,
|
||||
Cow::Borrowed(test_methods::PDA_SPEND_PROXY_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn claimer() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::CLAIMER_ID,
|
||||
Cow::Borrowed(test_methods::CLAIMER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn changer_claimer() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::CHANGER_CLAIMER_ID,
|
||||
Cow::Borrowed(test_methods::CHANGER_CLAIMER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn validity_window_chain_caller() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::VALIDITY_WINDOW_CHAIN_CALLER_ID,
|
||||
Cow::Borrowed(test_methods::VALIDITY_WINDOW_CHAIN_CALLER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn simple_transfer_proxy() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::SIMPLE_TRANSFER_PROXY_ID,
|
||||
Cow::Borrowed(test_methods::SIMPLE_TRANSFER_PROXY_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn malicious_injector() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::MALICIOUS_INJECTOR_ID,
|
||||
Cow::Borrowed(test_methods::MALICIOUS_INJECTOR_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn malicious_launderer() -> Program {
|
||||
Program::new_unchecked(
|
||||
test_methods::MALICIOUS_LAUNDERER_ID,
|
||||
Cow::Borrowed(test_methods::MALICIOUS_LAUNDERER_ELF),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,9 +9,9 @@ use lee_core::{
|
||||
use risc0_zkvm::{ExecutorEnv, InnerReceipt, ProverOpts, Receipt, default_prover};
|
||||
|
||||
use crate::{
|
||||
PRIVACY_PRESERVING_CIRCUIT_ELF, PRIVACY_PRESERVING_CIRCUIT_ID,
|
||||
error::{InvalidProgramBehaviorError, LeeError},
|
||||
program::Program,
|
||||
program_methods::{PRIVACY_PRESERVING_CIRCUIT_ELF, PRIVACY_PRESERVING_CIRCUIT_ID},
|
||||
state::MAX_NUMBER_CHAINED_CALLS,
|
||||
};
|
||||
|
||||
@ -224,7 +224,7 @@ mod tests {
|
||||
#[test]
|
||||
fn prove_privacy_preserving_execution_circuit_public_and_private_pre_accounts() {
|
||||
let recipient_keys = test_private_account_keys_1();
|
||||
let program = Program::authenticated_transfer_program();
|
||||
let program = crate::test_methods::simple_balance_transfer();
|
||||
let sender = AccountWithMetadata::new(
|
||||
Account {
|
||||
program_owner: program.id(),
|
||||
@ -261,10 +261,7 @@ mod tests {
|
||||
|
||||
let (output, proof) = execute_and_prove(
|
||||
vec![sender, recipient],
|
||||
Program::serialize_instruction(authenticated_transfer_core::Instruction::Transfer {
|
||||
amount: balance_to_move,
|
||||
})
|
||||
.unwrap(),
|
||||
Program::serialize_instruction(balance_to_move).unwrap(),
|
||||
vec![
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
@ -278,7 +275,7 @@ mod tests {
|
||||
identifier: 0,
|
||||
},
|
||||
],
|
||||
&Program::authenticated_transfer_program().into(),
|
||||
&crate::test_methods::simple_balance_transfer().into(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -304,7 +301,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn prove_privacy_preserving_execution_circuit_fully_private() {
|
||||
let program = Program::authenticated_transfer_program();
|
||||
let program = crate::test_methods::simple_balance_transfer();
|
||||
let sender_keys = test_private_account_keys_1();
|
||||
let recipient_keys = test_private_account_keys_2();
|
||||
|
||||
@ -339,7 +336,7 @@ mod tests {
|
||||
),
|
||||
];
|
||||
|
||||
let program = Program::authenticated_transfer_program();
|
||||
let program = crate::test_methods::simple_balance_transfer();
|
||||
|
||||
let expected_private_account_1 = Account {
|
||||
program_owner: program.id(),
|
||||
@ -366,10 +363,7 @@ mod tests {
|
||||
|
||||
let (output, proof) = execute_and_prove(
|
||||
vec![sender_pre, recipient],
|
||||
Program::serialize_instruction(authenticated_transfer_core::Instruction::Transfer {
|
||||
amount: balance_to_move,
|
||||
})
|
||||
.unwrap(),
|
||||
Program::serialize_instruction(balance_to_move).unwrap(),
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
@ -434,8 +428,8 @@ mod tests {
|
||||
AccountId::for_regular_private_account(&account_keys.npk(), 0),
|
||||
);
|
||||
|
||||
let validity_window_chain_caller = Program::validity_window_chain_caller();
|
||||
let validity_window = Program::validity_window();
|
||||
let validity_window_chain_caller = crate::test_methods::validity_window_chain_caller();
|
||||
let validity_window = crate::test_methods::validity_window();
|
||||
|
||||
let instruction = Program::serialize_instruction((
|
||||
Some(1_u64),
|
||||
@ -477,7 +471,7 @@ mod tests {
|
||||
/// to `PrivateAccountKind::Pda` carrying the correct `(program_id, seed, identifier)`.
|
||||
#[test]
|
||||
fn private_pda_claim_with_custom_identifier_encrypts_correct_kind() {
|
||||
let program = Program::pda_claimer();
|
||||
let program = crate::test_methods::pda_claimer();
|
||||
let keys = test_private_account_keys_1();
|
||||
let npk = keys.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
@ -513,13 +507,13 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
/// PDA init: initializes a new PDA under `authenticated_transfer`'s ownership.
|
||||
/// The `auth_transfer_proxy` program chains to `authenticated_transfer` with `pda_seeds`
|
||||
/// PDA init: initializes a new PDA under `simple_balance_transfer`'s ownership.
|
||||
/// The `simple_transfer_proxy` program chains to `simple_balance_transfer` with `pda_seeds`
|
||||
/// to establish authorization and the private PDA binding.
|
||||
#[test]
|
||||
fn private_pda_init() {
|
||||
let program = Program::auth_transfer_proxy();
|
||||
let auth_transfer = Program::authenticated_transfer_program();
|
||||
let program = crate::test_methods::simple_transfer_proxy();
|
||||
let simple_transfer = crate::test_methods::simple_balance_transfer();
|
||||
let keys = test_private_account_keys_1();
|
||||
let npk = keys.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
@ -530,9 +524,9 @@ mod tests {
|
||||
let pda_id = AccountId::for_private_pda(&program.id(), &seed, &npk, 0);
|
||||
let pda_pre = AccountWithMetadata::new(Account::default(), false, pda_id);
|
||||
|
||||
let auth_id = auth_transfer.id();
|
||||
let auth_id = simple_transfer.id();
|
||||
let program_with_deps =
|
||||
ProgramWithDependencies::new(program, [(auth_id, auth_transfer)].into());
|
||||
ProgramWithDependencies::new(program, [(auth_id, simple_transfer)].into());
|
||||
|
||||
// is_withdraw=false triggers init path (1 pre-state)
|
||||
let instruction = Program::serialize_instruction((seed, auth_id, 0_u128, false)).unwrap();
|
||||
@ -555,13 +549,13 @@ mod tests {
|
||||
assert_eq!(output.new_commitments.len(), 1);
|
||||
}
|
||||
|
||||
/// PDA withdraw: chains to `authenticated_transfer` to move balance from PDA to recipient.
|
||||
/// PDA withdraw: chains to `simple_balance_transfer` to move balance from PDA to recipient.
|
||||
/// Uses a default PDA (amount=0) because testing with a pre-funded PDA requires a
|
||||
/// two-tx sequence with membership proofs.
|
||||
#[test]
|
||||
fn private_pda_withdraw() {
|
||||
let program = Program::auth_transfer_proxy();
|
||||
let auth_transfer = Program::authenticated_transfer_program();
|
||||
let program = crate::test_methods::simple_transfer_proxy();
|
||||
let simple_transfer = crate::test_methods::simple_balance_transfer();
|
||||
let keys = test_private_account_keys_1();
|
||||
let npk = keys.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
@ -576,7 +570,7 @@ mod tests {
|
||||
let recipient_id = AccountId::new([88; 32]);
|
||||
let recipient_pre = AccountWithMetadata::new(
|
||||
Account {
|
||||
program_owner: auth_transfer.id(),
|
||||
program_owner: simple_transfer.id(),
|
||||
balance: 10000,
|
||||
..Account::default()
|
||||
},
|
||||
@ -584,9 +578,9 @@ mod tests {
|
||||
recipient_id,
|
||||
);
|
||||
|
||||
let auth_id = auth_transfer.id();
|
||||
let auth_id = simple_transfer.id();
|
||||
let program_with_deps =
|
||||
ProgramWithDependencies::new(program, [(auth_id, auth_transfer)].into());
|
||||
ProgramWithDependencies::new(program, [(auth_id, simple_transfer)].into());
|
||||
|
||||
// is_withdraw=true, amount=0 (PDA has no balance yet)
|
||||
let instruction = Program::serialize_instruction((seed, auth_id, 0_u128, true)).unwrap();
|
||||
@ -618,8 +612,8 @@ mod tests {
|
||||
/// uses the standard unauthorized private account path and works with auth-transfer's
|
||||
/// transfer path like any other private account.
|
||||
#[test]
|
||||
fn shared_account_receives_via_auth_transfer() {
|
||||
let program = Program::authenticated_transfer_program();
|
||||
fn shared_account_receives_via_simple_transfer() {
|
||||
let program = crate::test_methods::simple_balance_transfer();
|
||||
let shared_keys = test_private_account_keys_1();
|
||||
let shared_npk = shared_keys.npk();
|
||||
let shared_identifier: u128 = 42;
|
||||
@ -643,11 +637,7 @@ mod tests {
|
||||
let recipient = AccountWithMetadata::new(Account::default(), false, shared_account_id);
|
||||
|
||||
let balance_to_move: u128 = 100;
|
||||
let instruction =
|
||||
Program::serialize_instruction(authenticated_transfer_core::Instruction::Transfer {
|
||||
amount: balance_to_move,
|
||||
})
|
||||
.unwrap();
|
||||
let instruction = Program::serialize_instruction(balance_to_move).unwrap();
|
||||
|
||||
let result = execute_and_prove(
|
||||
vec![sender, recipient],
|
||||
@ -677,7 +667,7 @@ mod tests {
|
||||
/// to `PrivateAccountKind::Regular` carrying the correct identifier.
|
||||
#[test]
|
||||
fn private_authorized_init_encrypts_regular_kind_with_identifier() {
|
||||
let program = Program::authenticated_transfer_program();
|
||||
let program = crate::test_methods::simple_balance_transfer();
|
||||
let keys = test_private_account_keys_1();
|
||||
let identifier: u128 = 99;
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
@ -686,8 +676,7 @@ mod tests {
|
||||
|
||||
let (output, _) = execute_and_prove(
|
||||
vec![pre],
|
||||
Program::serialize_instruction(authenticated_transfer_core::Instruction::Initialize)
|
||||
.unwrap(),
|
||||
Program::serialize_instruction(0).unwrap(),
|
||||
vec![InputAccountIdentity::PrivateAuthorizedInit {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&keys.npk(), &keys.vpk()),
|
||||
@ -709,7 +698,7 @@ mod tests {
|
||||
/// to `PrivateAccountKind::Regular` carrying the correct identifier.
|
||||
#[test]
|
||||
fn private_unauthorized_init_encrypts_regular_kind_with_identifier() {
|
||||
let program = Program::authenticated_transfer_program();
|
||||
let program = crate::test_methods::simple_balance_transfer();
|
||||
let keys = test_private_account_keys_1();
|
||||
let identifier: u128 = 99;
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
@ -728,10 +717,7 @@ mod tests {
|
||||
|
||||
let (output, _) = execute_and_prove(
|
||||
vec![sender, recipient],
|
||||
Program::serialize_instruction(authenticated_transfer_core::Instruction::Transfer {
|
||||
amount: 1,
|
||||
})
|
||||
.unwrap(),
|
||||
Program::serialize_instruction(1).unwrap(),
|
||||
vec![
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
@ -756,7 +742,7 @@ mod tests {
|
||||
/// to `PrivateAccountKind::Regular` carrying the correct identifier.
|
||||
#[test]
|
||||
fn private_authorized_update_encrypts_regular_kind_with_identifier() {
|
||||
let program = Program::authenticated_transfer_program();
|
||||
let program = crate::test_methods::simple_balance_transfer();
|
||||
let keys = test_private_account_keys_1();
|
||||
let identifier: u128 = 99;
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
@ -775,10 +761,7 @@ mod tests {
|
||||
|
||||
let (output, _) = execute_and_prove(
|
||||
vec![sender, recipient],
|
||||
Program::serialize_instruction(authenticated_transfer_core::Instruction::Transfer {
|
||||
amount: 1,
|
||||
})
|
||||
.unwrap(),
|
||||
Program::serialize_instruction(1).unwrap(),
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
@ -804,18 +787,18 @@ mod tests {
|
||||
/// to `PrivateAccountKind::Pda` carrying the correct `(program_id, seed, identifier)`.
|
||||
#[test]
|
||||
fn private_pda_update_encrypts_pda_kind_with_identifier() {
|
||||
let program = Program::pda_spend_proxy();
|
||||
let auth_transfer = Program::authenticated_transfer_program();
|
||||
let program = crate::test_methods::pda_spend_proxy();
|
||||
let simple_transfer = crate::test_methods::simple_balance_transfer();
|
||||
let keys = test_private_account_keys_1();
|
||||
let npk = keys.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
let identifier: u128 = 99;
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
|
||||
let auth_transfer_id = auth_transfer.id();
|
||||
let simple_transfer_id = simple_transfer.id();
|
||||
let pda_id = AccountId::for_private_pda(&program.id(), &seed, &npk, identifier);
|
||||
let pda_account = Account {
|
||||
program_owner: auth_transfer_id,
|
||||
program_owner: simple_transfer_id,
|
||||
balance: 1,
|
||||
..Account::default()
|
||||
};
|
||||
@ -829,12 +812,12 @@ mod tests {
|
||||
|
||||
let program_with_deps = ProgramWithDependencies::new(
|
||||
program.clone(),
|
||||
[(auth_transfer_id, auth_transfer)].into(),
|
||||
[(simple_transfer_id, simple_transfer)].into(),
|
||||
);
|
||||
|
||||
let (output, _) = execute_and_prove(
|
||||
vec![pda_pre, recipient_pre],
|
||||
Program::serialize_instruction((seed, 1_u128, auth_transfer_id, false)).unwrap(),
|
||||
Program::serialize_instruction((seed, 1_u128, simple_transfer_id, false)).unwrap(),
|
||||
vec![
|
||||
InputAccountIdentity::PrivatePdaUpdate {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
@ -863,7 +846,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn private_pda_init_identifier_mismatch_fails() {
|
||||
let program = Program::pda_claimer();
|
||||
let program = crate::test_methods::pda_claimer();
|
||||
let keys = test_private_account_keys_1();
|
||||
let npk = keys.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
@ -892,17 +875,17 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn private_pda_update_identifier_mismatch_fails() {
|
||||
let program = Program::pda_spend_proxy();
|
||||
let auth_transfer = Program::authenticated_transfer_program();
|
||||
let program = crate::test_methods::pda_spend_proxy();
|
||||
let simple_transfer = crate::test_methods::simple_balance_transfer();
|
||||
let keys = test_private_account_keys_1();
|
||||
let npk = keys.npk();
|
||||
let seed = PdaSeed::new([42; 32]);
|
||||
let ssk = SharedSecretKey::encapsulate_deterministic(&keys.vpk(), &[0_u8; 32], 0).0;
|
||||
|
||||
let auth_transfer_id = auth_transfer.id();
|
||||
let simple_transfer_id = simple_transfer.id();
|
||||
let pda_id = AccountId::for_private_pda(&program.id(), &seed, &npk, 5);
|
||||
let pda_account = Account {
|
||||
program_owner: auth_transfer_id,
|
||||
program_owner: simple_transfer_id,
|
||||
balance: 1,
|
||||
..Account::default()
|
||||
};
|
||||
@ -915,11 +898,11 @@ mod tests {
|
||||
AccountWithMetadata::new(Account::default(), true, AccountId::new([0; 32]));
|
||||
|
||||
let program_with_deps =
|
||||
ProgramWithDependencies::new(program, [(auth_transfer_id, auth_transfer)].into());
|
||||
ProgramWithDependencies::new(program, [(simple_transfer_id, simple_transfer)].into());
|
||||
|
||||
let result = execute_and_prove(
|
||||
vec![pda_pre, recipient_pre],
|
||||
Program::serialize_instruction((seed, 1_u128, auth_transfer_id, false)).unwrap(),
|
||||
Program::serialize_instruction((seed, 1_u128, simple_transfer_id, false)).unwrap(),
|
||||
vec![
|
||||
InputAccountIdentity::PrivatePdaUpdate {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use borsh::{BorshDeserialize, BorshSerialize};
|
||||
use lee_core::{
|
||||
account::AccountWithMetadata,
|
||||
@ -6,15 +8,7 @@ use lee_core::{
|
||||
use risc0_zkvm::{ExecutorEnv, ExecutorEnvBuilder, default_executor, serde::to_vec};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
error::LeeError,
|
||||
program_methods::{
|
||||
AMM_ELF, AMM_ID, ASSOCIATED_TOKEN_ACCOUNT_ELF, ASSOCIATED_TOKEN_ACCOUNT_ID,
|
||||
AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID, BRIDGE_ELF, BRIDGE_ID, CLOCK_ELF,
|
||||
CLOCK_ID, FAUCET_ELF, FAUCET_ID, PINATA_ELF, PINATA_ID, TOKEN_ELF, TOKEN_ID, VAULT_ELF,
|
||||
VAULT_ID,
|
||||
},
|
||||
};
|
||||
use crate::error::LeeError;
|
||||
|
||||
/// Maximum number of cycles for a public execution.
|
||||
/// TODO: Make this variable when fees are implemented.
|
||||
@ -23,18 +17,23 @@ const MAX_NUM_CYCLES_PUBLIC_EXECUTION: u64 = 1024 * 1024 * 32; // 32M cycles
|
||||
#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
|
||||
pub struct Program {
|
||||
id: ProgramId,
|
||||
elf: Vec<u8>,
|
||||
elf: Cow<'static, [u8]>,
|
||||
}
|
||||
|
||||
impl Program {
|
||||
pub fn new(bytecode: Vec<u8>) -> Result<Self, LeeError> {
|
||||
let binary = risc0_binfmt::ProgramBinary::decode(&bytecode)
|
||||
pub fn new(elf: Cow<'static, [u8]>) -> Result<Self, LeeError> {
|
||||
let binary = risc0_binfmt::ProgramBinary::decode(elf.as_ref())
|
||||
.map_err(LeeError::InvalidProgramBytecode)?;
|
||||
let id = binary
|
||||
.compute_image_id()
|
||||
.map_err(LeeError::InvalidProgramBytecode)?
|
||||
.into();
|
||||
Ok(Self { elf: bytecode, id })
|
||||
Ok(Self { id, elf })
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn new_unchecked(id: ProgramId, elf: Cow<'static, [u8]>) -> Self {
|
||||
Self { id, elf }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
@ -109,412 +108,17 @@ impl Program {
|
||||
.map_err(|e| LeeError::ProgramWriteInputFailed(e.to_string()))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn authenticated_transfer_program() -> Self {
|
||||
Self {
|
||||
id: AUTHENTICATED_TRANSFER_ID,
|
||||
elf: AUTHENTICATED_TRANSFER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn token() -> Self {
|
||||
Self {
|
||||
id: TOKEN_ID,
|
||||
elf: TOKEN_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn amm() -> Self {
|
||||
Self {
|
||||
id: AMM_ID,
|
||||
elf: AMM_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn clock() -> Self {
|
||||
Self {
|
||||
id: CLOCK_ID,
|
||||
elf: CLOCK_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn ata() -> Self {
|
||||
Self {
|
||||
id: ASSOCIATED_TOKEN_ACCOUNT_ID,
|
||||
elf: ASSOCIATED_TOKEN_ACCOUNT_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn vault() -> Self {
|
||||
Self {
|
||||
id: VAULT_ID,
|
||||
elf: VAULT_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn faucet() -> Self {
|
||||
Self {
|
||||
id: FAUCET_ID,
|
||||
elf: FAUCET_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn bridge() -> Self {
|
||||
Self {
|
||||
id: BRIDGE_ID,
|
||||
elf: BRIDGE_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Testnet only. Refactor to prevent compilation on mainnet.
|
||||
impl Program {
|
||||
#[must_use]
|
||||
pub fn pinata() -> Self {
|
||||
Self {
|
||||
id: PINATA_ID,
|
||||
elf: PINATA_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn pinata_token() -> Self {
|
||||
use crate::program_methods::{PINATA_TOKEN_ELF, PINATA_TOKEN_ID};
|
||||
Self {
|
||||
id: PINATA_TOKEN_ID,
|
||||
elf: PINATA_TOKEN_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use lee_core::account::{Account, AccountId, AccountWithMetadata};
|
||||
|
||||
use crate::{
|
||||
program::Program,
|
||||
program_methods::{
|
||||
AMM_ELF, AMM_ID, ASSOCIATED_TOKEN_ACCOUNT_ELF, ASSOCIATED_TOKEN_ACCOUNT_ID,
|
||||
AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID, BRIDGE_ELF, BRIDGE_ID,
|
||||
CLOCK_ELF, CLOCK_ID, FAUCET_ELF, FAUCET_ID, PINATA_ELF, PINATA_ID, PINATA_TOKEN_ELF,
|
||||
PINATA_TOKEN_ID, TOKEN_ELF, TOKEN_ID, VAULT_ELF, VAULT_ID,
|
||||
},
|
||||
};
|
||||
|
||||
impl Program {
|
||||
/// A program that changes the nonce of an account.
|
||||
#[must_use]
|
||||
pub fn nonce_changer_program() -> Self {
|
||||
use test_program_methods::{NONCE_CHANGER_ELF, NONCE_CHANGER_ID};
|
||||
|
||||
Self {
|
||||
id: NONCE_CHANGER_ID,
|
||||
elf: NONCE_CHANGER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
/// A program that produces more output accounts than the inputs it received.
|
||||
#[must_use]
|
||||
pub fn extra_output_program() -> Self {
|
||||
use test_program_methods::{EXTRA_OUTPUT_ELF, EXTRA_OUTPUT_ID};
|
||||
|
||||
Self {
|
||||
id: EXTRA_OUTPUT_ID,
|
||||
elf: EXTRA_OUTPUT_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
/// A program that produces less output accounts than the inputs it received.
|
||||
#[must_use]
|
||||
pub fn missing_output_program() -> Self {
|
||||
use test_program_methods::{MISSING_OUTPUT_ELF, MISSING_OUTPUT_ID};
|
||||
|
||||
Self {
|
||||
id: MISSING_OUTPUT_ID,
|
||||
elf: MISSING_OUTPUT_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
/// A program that changes the program owner of an account to [0, 1, 2, 3, 4, 5, 6, 7].
|
||||
#[must_use]
|
||||
pub fn program_owner_changer() -> Self {
|
||||
use test_program_methods::{PROGRAM_OWNER_CHANGER_ELF, PROGRAM_OWNER_CHANGER_ID};
|
||||
|
||||
Self {
|
||||
id: PROGRAM_OWNER_CHANGER_ID,
|
||||
elf: PROGRAM_OWNER_CHANGER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
/// A program that transfers balance without caring about authorizations.
|
||||
#[must_use]
|
||||
pub fn simple_balance_transfer() -> Self {
|
||||
use test_program_methods::{SIMPLE_BALANCE_TRANSFER_ELF, SIMPLE_BALANCE_TRANSFER_ID};
|
||||
|
||||
Self {
|
||||
id: SIMPLE_BALANCE_TRANSFER_ID,
|
||||
elf: SIMPLE_BALANCE_TRANSFER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
/// A program that modifies the data of an account.
|
||||
#[must_use]
|
||||
pub fn data_changer() -> Self {
|
||||
use test_program_methods::{DATA_CHANGER_ELF, DATA_CHANGER_ID};
|
||||
|
||||
Self {
|
||||
id: DATA_CHANGER_ID,
|
||||
elf: DATA_CHANGER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
/// A program that mints balance.
|
||||
#[must_use]
|
||||
pub fn minter() -> Self {
|
||||
use test_program_methods::{MINTER_ELF, MINTER_ID};
|
||||
|
||||
Self {
|
||||
id: MINTER_ID,
|
||||
elf: MINTER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
/// A program that burns balance.
|
||||
#[must_use]
|
||||
pub fn burner() -> Self {
|
||||
use test_program_methods::{BURNER_ELF, BURNER_ID};
|
||||
|
||||
Self {
|
||||
id: BURNER_ID,
|
||||
elf: BURNER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn chain_caller() -> Self {
|
||||
use test_program_methods::{CHAIN_CALLER_ELF, CHAIN_CALLER_ID};
|
||||
|
||||
Self {
|
||||
id: CHAIN_CALLER_ID,
|
||||
elf: CHAIN_CALLER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn claimer() -> Self {
|
||||
use test_program_methods::{CLAIMER_ELF, CLAIMER_ID};
|
||||
|
||||
Self {
|
||||
id: CLAIMER_ID,
|
||||
elf: CLAIMER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn pda_claimer() -> Self {
|
||||
use test_program_methods::{PDA_CLAIMER_ELF, PDA_CLAIMER_ID};
|
||||
|
||||
Self {
|
||||
id: PDA_CLAIMER_ID,
|
||||
elf: PDA_CLAIMER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn private_pda_delegator() -> Self {
|
||||
use test_program_methods::{PRIVATE_PDA_DELEGATOR_ELF, PRIVATE_PDA_DELEGATOR_ID};
|
||||
|
||||
Self {
|
||||
id: PRIVATE_PDA_DELEGATOR_ID,
|
||||
elf: PRIVATE_PDA_DELEGATOR_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn auth_transfer_proxy() -> Self {
|
||||
use test_program_methods::{AUTH_TRANSFER_PROXY_ELF, AUTH_TRANSFER_PROXY_ID};
|
||||
|
||||
Self {
|
||||
id: AUTH_TRANSFER_PROXY_ID,
|
||||
elf: AUTH_TRANSFER_PROXY_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn two_pda_claimer() -> Self {
|
||||
use test_program_methods::{TWO_PDA_CLAIMER_ELF, TWO_PDA_CLAIMER_ID};
|
||||
|
||||
Self {
|
||||
id: TWO_PDA_CLAIMER_ID,
|
||||
elf: TWO_PDA_CLAIMER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn pda_spend_proxy() -> Self {
|
||||
use test_program_methods::{PDA_SPEND_PROXY_ELF, PDA_SPEND_PROXY_ID};
|
||||
|
||||
Self {
|
||||
id: PDA_SPEND_PROXY_ID,
|
||||
elf: PDA_SPEND_PROXY_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn changer_claimer() -> Self {
|
||||
use test_program_methods::{CHANGER_CLAIMER_ELF, CHANGER_CLAIMER_ID};
|
||||
|
||||
Self {
|
||||
id: CHANGER_CLAIMER_ID,
|
||||
elf: CHANGER_CLAIMER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn noop() -> Self {
|
||||
use test_program_methods::{NOOP_ELF, NOOP_ID};
|
||||
|
||||
Self {
|
||||
id: NOOP_ID,
|
||||
elf: NOOP_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn auth_asserting_noop() -> Self {
|
||||
use test_program_methods::{AUTH_ASSERTING_NOOP_ELF, AUTH_ASSERTING_NOOP_ID};
|
||||
|
||||
Self {
|
||||
id: AUTH_ASSERTING_NOOP_ID,
|
||||
elf: AUTH_ASSERTING_NOOP_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn malicious_authorization_changer() -> Self {
|
||||
use test_program_methods::{
|
||||
MALICIOUS_AUTHORIZATION_CHANGER_ELF, MALICIOUS_AUTHORIZATION_CHANGER_ID,
|
||||
};
|
||||
|
||||
Self {
|
||||
id: MALICIOUS_AUTHORIZATION_CHANGER_ID,
|
||||
elf: MALICIOUS_AUTHORIZATION_CHANGER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn modified_transfer_program() -> Self {
|
||||
use test_program_methods::{MODIFIED_TRANSFER_ELF, MODIFIED_TRANSFER_ID};
|
||||
Self {
|
||||
id: MODIFIED_TRANSFER_ID,
|
||||
elf: MODIFIED_TRANSFER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn validity_window() -> Self {
|
||||
use test_program_methods::{VALIDITY_WINDOW_ELF, VALIDITY_WINDOW_ID};
|
||||
Self {
|
||||
id: VALIDITY_WINDOW_ID,
|
||||
elf: VALIDITY_WINDOW_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn validity_window_chain_caller() -> Self {
|
||||
use test_program_methods::{
|
||||
VALIDITY_WINDOW_CHAIN_CALLER_ELF, VALIDITY_WINDOW_CHAIN_CALLER_ID,
|
||||
};
|
||||
Self {
|
||||
id: VALIDITY_WINDOW_CHAIN_CALLER_ID,
|
||||
elf: VALIDITY_WINDOW_CHAIN_CALLER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn flash_swap_initiator() -> Self {
|
||||
use test_program_methods::FLASH_SWAP_INITIATOR_ELF;
|
||||
Self::new(FLASH_SWAP_INITIATOR_ELF.to_vec())
|
||||
.expect("flash_swap_initiator must be a valid Risc0 program")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn flash_swap_callback() -> Self {
|
||||
use test_program_methods::FLASH_SWAP_CALLBACK_ELF;
|
||||
Self::new(FLASH_SWAP_CALLBACK_ELF.to_vec())
|
||||
.expect("flash_swap_callback must be a valid Risc0 program")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn malicious_self_program_id() -> Self {
|
||||
use test_program_methods::MALICIOUS_SELF_PROGRAM_ID_ELF;
|
||||
Self::new(MALICIOUS_SELF_PROGRAM_ID_ELF.to_vec())
|
||||
.expect("malicious_self_program_id must be a valid Risc0 program")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn malicious_caller_program_id() -> Self {
|
||||
use test_program_methods::MALICIOUS_CALLER_PROGRAM_ID_ELF;
|
||||
Self::new(MALICIOUS_CALLER_PROGRAM_ID_ELF.to_vec())
|
||||
.expect("malicious_caller_program_id must be a valid Risc0 program")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn time_locked_transfer() -> Self {
|
||||
use test_program_methods::TIME_LOCKED_TRANSFER_ELF;
|
||||
Self::new(TIME_LOCKED_TRANSFER_ELF.to_vec()).unwrap()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn pinata_cooldown() -> Self {
|
||||
use test_program_methods::PINATA_COOLDOWN_ELF;
|
||||
Self::new(PINATA_COOLDOWN_ELF.to_vec()).unwrap()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn malicious_injector() -> Self {
|
||||
use test_program_methods::{MALICIOUS_INJECTOR_ELF, MALICIOUS_INJECTOR_ID};
|
||||
Self {
|
||||
id: MALICIOUS_INJECTOR_ID,
|
||||
elf: MALICIOUS_INJECTOR_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn malicious_launderer() -> Self {
|
||||
use test_program_methods::{MALICIOUS_LAUNDERER_ELF, MALICIOUS_LAUNDERER_ID};
|
||||
Self {
|
||||
id: MALICIOUS_LAUNDERER_ID,
|
||||
elf: MALICIOUS_LAUNDERER_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn elf_returns_the_program_bytecode_constant() {
|
||||
// `Program::elf` must return exactly the compile-time ELF, never an empty
|
||||
// or placeholder slice. Catches mutations returning `Vec::leak(Vec::new())`,
|
||||
// `Vec::leak(vec![0])`, or `Vec::leak(vec![1])`.
|
||||
let at = Program::authenticated_transfer_program();
|
||||
assert!(!at.elf().is_empty());
|
||||
assert_eq!(at.elf(), AUTHENTICATED_TRANSFER_ELF);
|
||||
|
||||
let token = Program::token();
|
||||
assert!(!token.elf().is_empty());
|
||||
assert_eq!(token.elf(), TOKEN_ELF);
|
||||
}
|
||||
use crate::program::Program;
|
||||
|
||||
#[test]
|
||||
fn program_execution() {
|
||||
let program = Program::simple_balance_transfer();
|
||||
let program = crate::test_methods::simple_balance_transfer();
|
||||
let balance_to_move: u128 = 11_223_344_556_677;
|
||||
let instruction_data = Program::serialize_instruction(balance_to_move).unwrap();
|
||||
let sender = AccountWithMetadata::new(
|
||||
@ -545,47 +149,4 @@ mod tests {
|
||||
assert_eq!(sender_post.account(), &expected_sender_post);
|
||||
assert_eq!(recipient_post.account(), &expected_recipient_post);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_programs() {
|
||||
let auth_transfer_program = Program::authenticated_transfer_program();
|
||||
let token_program = Program::token();
|
||||
let vault_program = Program::vault();
|
||||
let faucet_program = Program::faucet();
|
||||
let bridge_program = Program::bridge();
|
||||
let pinata_program = Program::pinata();
|
||||
|
||||
assert_eq!(auth_transfer_program.id, AUTHENTICATED_TRANSFER_ID);
|
||||
assert_eq!(auth_transfer_program.elf, AUTHENTICATED_TRANSFER_ELF);
|
||||
assert_eq!(token_program.id, TOKEN_ID);
|
||||
assert_eq!(token_program.elf, TOKEN_ELF);
|
||||
assert_eq!(vault_program.id, VAULT_ID);
|
||||
assert_eq!(vault_program.elf, VAULT_ELF);
|
||||
assert_eq!(faucet_program.id, FAUCET_ID);
|
||||
assert_eq!(faucet_program.elf, FAUCET_ELF);
|
||||
assert_eq!(bridge_program.id, BRIDGE_ID);
|
||||
assert_eq!(bridge_program.elf, BRIDGE_ELF);
|
||||
assert_eq!(pinata_program.id, PINATA_ID);
|
||||
assert_eq!(pinata_program.elf, PINATA_ELF);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_program_ids_match_elfs() {
|
||||
let cases: &[(&[u8], [u32; 8])] = &[
|
||||
(AMM_ELF, AMM_ID),
|
||||
(AUTHENTICATED_TRANSFER_ELF, AUTHENTICATED_TRANSFER_ID),
|
||||
(ASSOCIATED_TOKEN_ACCOUNT_ELF, ASSOCIATED_TOKEN_ACCOUNT_ID),
|
||||
(CLOCK_ELF, CLOCK_ID),
|
||||
(FAUCET_ELF, FAUCET_ID),
|
||||
(BRIDGE_ELF, BRIDGE_ID),
|
||||
(PINATA_ELF, PINATA_ID),
|
||||
(PINATA_TOKEN_ELF, PINATA_TOKEN_ID),
|
||||
(TOKEN_ELF, TOKEN_ID),
|
||||
(VAULT_ELF, VAULT_ID),
|
||||
];
|
||||
for (elf, expected_id) in cases {
|
||||
let program = Program::new(elf.to_vec()).unwrap();
|
||||
assert_eq!(program.id(), *expected_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +66,6 @@ pub mod tests {
|
||||
use crate::{
|
||||
AccountId, PrivateKey, PublicKey, PublicTransaction, Signature, V03State,
|
||||
error::LeeError,
|
||||
program::Program,
|
||||
public_transaction::{Message, WitnessSet},
|
||||
validated_state_diff::ValidatedStateDiff,
|
||||
};
|
||||
@ -82,7 +81,9 @@ pub mod tests {
|
||||
fn state_for_tests() -> V03State {
|
||||
let (_, _, addr1, addr2) = keys_for_tests();
|
||||
let initial_data = [(addr1, 10000), (addr2, 20000)];
|
||||
V03State::new_with_genesis_accounts(&initial_data, vec![], 0)
|
||||
V03State::new()
|
||||
.with_public_account_balances(initial_data)
|
||||
.with_programs([crate::test_methods::simple_balance_transfer()])
|
||||
}
|
||||
|
||||
fn transaction_for_tests() -> PublicTransaction {
|
||||
@ -90,7 +91,7 @@ pub mod tests {
|
||||
let nonces = vec![0_u128.into(), 0_u128.into()];
|
||||
let instruction = 1337;
|
||||
let message = Message::try_new(
|
||||
Program::authenticated_transfer_program().id(),
|
||||
crate::test_methods::simple_balance_transfer().id(),
|
||||
vec![addr1, addr2],
|
||||
nonces,
|
||||
instruction,
|
||||
@ -168,7 +169,7 @@ pub mod tests {
|
||||
let nonces = vec![0_u128.into(), 0_u128.into()];
|
||||
let instruction = 1337;
|
||||
let message = Message::try_new(
|
||||
Program::authenticated_transfer_program().id(),
|
||||
crate::test_methods::simple_balance_transfer().id(),
|
||||
vec![addr1, addr1],
|
||||
nonces,
|
||||
instruction,
|
||||
@ -188,7 +189,7 @@ pub mod tests {
|
||||
let nonces = vec![0_u128.into()];
|
||||
let instruction = 1337;
|
||||
let message = Message::try_new(
|
||||
Program::authenticated_transfer_program().id(),
|
||||
crate::test_methods::simple_balance_transfer().id(),
|
||||
vec![addr1, addr2],
|
||||
nonces,
|
||||
instruction,
|
||||
@ -208,7 +209,7 @@ pub mod tests {
|
||||
let nonces = vec![0_u128.into(), 0_u128.into()];
|
||||
let instruction = 1337;
|
||||
let message = Message::try_new(
|
||||
Program::authenticated_transfer_program().id(),
|
||||
crate::test_methods::simple_balance_transfer().id(),
|
||||
vec![addr1, addr2],
|
||||
nonces,
|
||||
instruction,
|
||||
@ -229,7 +230,7 @@ pub mod tests {
|
||||
let nonces = vec![0_u128.into(), 1_u128.into()];
|
||||
let instruction = 1337;
|
||||
let message = Message::try_new(
|
||||
Program::authenticated_transfer_program().id(),
|
||||
crate::test_methods::simple_balance_transfer().id(),
|
||||
vec![addr1, addr2],
|
||||
nonces,
|
||||
instruction,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -457,7 +457,7 @@ impl ValidatedStateDiff {
|
||||
state: &V03State,
|
||||
) -> Result<Self, LeeError> {
|
||||
// TODO: remove clone
|
||||
let program = Program::new(tx.message.bytecode.clone())?;
|
||||
let program = Program::new(tx.message.bytecode.clone().into())?;
|
||||
if state.programs().contains_key(&program.id()) {
|
||||
return Err(LeeError::ProgramAlreadyExists);
|
||||
}
|
||||
@ -511,7 +511,9 @@ fn n_unique<T: Eq + Hash>(data: &[T]) -> usize {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use lee_core::account::{AccountId, Nonce};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use lee_core::account::{Account, AccountId, Nonce};
|
||||
|
||||
use crate::{
|
||||
PrivateKey, PublicKey, V03State,
|
||||
@ -521,27 +523,42 @@ mod tests {
|
||||
validated_state_diff::ValidatedStateDiff,
|
||||
};
|
||||
|
||||
fn public_state_from_balances(
|
||||
initial_data: &[(AccountId, u128)],
|
||||
) -> HashMap<AccountId, Account> {
|
||||
initial_data
|
||||
.iter()
|
||||
.copied()
|
||||
.map(|(account_id, balance)| {
|
||||
(
|
||||
account_id,
|
||||
Account {
|
||||
balance,
|
||||
..Account::default()
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_diff_reflects_a_successful_transfer() {
|
||||
// A successful native transfer must record the debited sender in
|
||||
// `public_diff()`. Catches the mutation that replaces `public_diff` with
|
||||
// `HashMap::new()` (which would hide every account change).
|
||||
use authenticated_transfer_core::Instruction as AtInstruction;
|
||||
|
||||
let from_key = PrivateKey::try_new([1_u8; 32]).unwrap();
|
||||
let from = AccountId::from(&PublicKey::new_from_private_key(&from_key));
|
||||
let to_key = PrivateKey::try_new([2_u8; 32]).unwrap();
|
||||
let to = AccountId::from(&PublicKey::new_from_private_key(&to_key));
|
||||
|
||||
let state = V03State::new_with_genesis_accounts(&[(from, 100)], vec![], 0);
|
||||
let program_id = Program::authenticated_transfer_program().id();
|
||||
let message = Message::try_new(
|
||||
program_id,
|
||||
vec![from, to],
|
||||
vec![Nonce(0), Nonce(0)],
|
||||
AtInstruction::Transfer { amount: 5 },
|
||||
)
|
||||
.unwrap();
|
||||
let state = V03State::new()
|
||||
.with_public_accounts(public_state_from_balances(&[(from, 100)]))
|
||||
.with_programs(std::iter::once(
|
||||
crate::test_methods::simple_balance_transfer(),
|
||||
));
|
||||
let program_id = crate::test_methods::simple_balance_transfer().id();
|
||||
let message =
|
||||
Message::try_new(program_id, vec![from, to], vec![Nonce(0), Nonce(0)], 5).unwrap();
|
||||
let witness_set = WitnessSet::for_message(&message, &[&from_key, &to_key]);
|
||||
let tx = crate::PublicTransaction::new(message, witness_set);
|
||||
|
||||
@ -591,7 +608,7 @@ mod tests {
|
||||
|
||||
type InjectorInstruction = (
|
||||
lee_core::program::ProgramId, // p2_id
|
||||
lee_core::program::ProgramId, // auth_transfer_id
|
||||
lee_core::program::ProgramId, // simple_balance_transfer_id
|
||||
[u8; 32], // victim_id_raw
|
||||
u128, // victim_balance
|
||||
u128, // victim_nonce
|
||||
@ -609,18 +626,21 @@ mod tests {
|
||||
let recipient_id = AccountId::new([42_u8; 32]);
|
||||
let victim_balance = 5_000_u128;
|
||||
|
||||
// genesis sets program_owner = authenticated_transfer_program.id() on all accounts.
|
||||
let mut state = V03State::new_with_genesis_accounts(
|
||||
&[(victim_id, victim_balance), (recipient_id, 0)],
|
||||
vec![],
|
||||
0,
|
||||
);
|
||||
state.insert_program(Program::malicious_injector());
|
||||
state.insert_program(Program::malicious_launderer());
|
||||
// genesis sets program_owner = simple_balance_transfer_program.id() on all accounts.
|
||||
let state = V03State::new()
|
||||
.with_public_accounts(public_state_from_balances(&[
|
||||
(victim_id, victim_balance),
|
||||
(recipient_id, 0),
|
||||
]))
|
||||
.with_programs([
|
||||
crate::test_methods::simple_balance_transfer(),
|
||||
crate::test_methods::malicious_injector(),
|
||||
crate::test_methods::malicious_launderer(),
|
||||
]);
|
||||
|
||||
// Build attacker's private account and its local commitment tree.
|
||||
let attacker_account = Account {
|
||||
program_owner: Program::authenticated_transfer_program().id(),
|
||||
program_owner: crate::test_methods::simple_balance_transfer().id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
};
|
||||
@ -635,8 +655,8 @@ mod tests {
|
||||
|
||||
let victim_account = state.get_account_by_id(victim_id);
|
||||
let instruction: InjectorInstruction = (
|
||||
Program::malicious_launderer().id(),
|
||||
Program::authenticated_transfer_program().id(),
|
||||
crate::test_methods::malicious_launderer().id(),
|
||||
crate::test_methods::simple_balance_transfer().id(),
|
||||
*victim_id.value(),
|
||||
victim_account.balance,
|
||||
victim_account.nonce.0,
|
||||
@ -646,17 +666,17 @@ mod tests {
|
||||
);
|
||||
let instruction_data = Program::serialize_instruction(instruction).unwrap();
|
||||
|
||||
let p2 = Program::malicious_launderer();
|
||||
let at = Program::authenticated_transfer_program();
|
||||
let p2 = crate::test_methods::malicious_launderer();
|
||||
let at = crate::test_methods::simple_balance_transfer();
|
||||
let program_with_deps = ProgramWithDependencies::new(
|
||||
Program::malicious_injector(),
|
||||
crate::test_methods::malicious_injector(),
|
||||
[(p2.id(), p2), (at.id(), at)].into(),
|
||||
);
|
||||
|
||||
// account_identities order must match self.pre_states as built by the circuit:
|
||||
// [0] attacker — first seen in P1's program_output.pre_states
|
||||
// [1] victim — first seen in authenticated_transfer's program_output.pre_states
|
||||
// [2] recipient — first seen in authenticated_transfer's program_output.pre_states
|
||||
// [1] victim — first seen in simple_balance_transfer's program_output.pre_states
|
||||
// [2] recipient — first seen in simple_balance_transfer's program_output.pre_states
|
||||
let account_identities = vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
epk: attacker_epk,
|
||||
@ -746,7 +766,7 @@ mod tests {
|
||||
|
||||
type InjectorInstruction = (
|
||||
lee_core::program::ProgramId, // p2_id
|
||||
lee_core::program::ProgramId, // auth_transfer_id
|
||||
lee_core::program::ProgramId, // simple_balance_transfer_id
|
||||
[u8; 32], // victim_id_raw
|
||||
u128, // victim_balance
|
||||
u128, // victim_nonce
|
||||
@ -768,13 +788,17 @@ mod tests {
|
||||
let recipient_id = AccountId::new([42_u8; 32]);
|
||||
|
||||
// Victim has no public state entry; only recipient is registered at genesis.
|
||||
let mut state = V03State::new_with_genesis_accounts(&[(recipient_id, 0)], vec![], 0);
|
||||
state.insert_program(Program::malicious_injector());
|
||||
state.insert_program(Program::malicious_launderer());
|
||||
let state = V03State::new()
|
||||
.with_public_accounts(public_state_from_balances(&[(recipient_id, 0)]))
|
||||
.with_programs([
|
||||
crate::test_methods::simple_balance_transfer(),
|
||||
crate::test_methods::malicious_injector(),
|
||||
crate::test_methods::malicious_launderer(),
|
||||
]);
|
||||
|
||||
// Build attacker's private account and its local commitment tree.
|
||||
let attacker_account = Account {
|
||||
program_owner: Program::authenticated_transfer_program().id(),
|
||||
program_owner: crate::test_methods::simple_balance_transfer().id(),
|
||||
balance: 100,
|
||||
..Account::default()
|
||||
};
|
||||
@ -788,32 +812,32 @@ mod tests {
|
||||
let attacker_pre = AccountWithMetadata::new(attacker_account, true, attacker_id);
|
||||
|
||||
// The attacker supplies the victim's account data directly — it cannot be read from
|
||||
// public state. The injected balance and program_owner allow authenticated_transfer
|
||||
// public state. The injected balance and program_owner allow simple_balance_transfer
|
||||
// to succeed inside the circuit, which has no access to chain state and cannot detect
|
||||
// that these values are fabricated.
|
||||
let instruction: InjectorInstruction = (
|
||||
Program::malicious_launderer().id(),
|
||||
Program::authenticated_transfer_program().id(),
|
||||
crate::test_methods::malicious_launderer().id(),
|
||||
crate::test_methods::simple_balance_transfer().id(),
|
||||
*victim_id.value(),
|
||||
victim_balance,
|
||||
0_u128, // nonce
|
||||
Program::authenticated_transfer_program().id(), // program_owner
|
||||
0_u128, // nonce
|
||||
crate::test_methods::simple_balance_transfer().id(), // program_owner
|
||||
*recipient_id.value(),
|
||||
victim_balance,
|
||||
);
|
||||
let instruction_data = Program::serialize_instruction(instruction).unwrap();
|
||||
|
||||
let p2 = Program::malicious_launderer();
|
||||
let at = Program::authenticated_transfer_program();
|
||||
let p2 = crate::test_methods::malicious_launderer();
|
||||
let at = crate::test_methods::simple_balance_transfer();
|
||||
let program_with_deps = ProgramWithDependencies::new(
|
||||
Program::malicious_injector(),
|
||||
crate::test_methods::malicious_injector(),
|
||||
[(p2.id(), p2), (at.id(), at)].into(),
|
||||
);
|
||||
|
||||
// account_identities order must match self.pre_states as built by the circuit:
|
||||
// [0] attacker — first seen in P1's program_output.pre_states
|
||||
// [1] victim — first seen in authenticated_transfer's program_output.pre_states
|
||||
// [2] recipient — first seen in authenticated_transfer's program_output.pre_states
|
||||
// [1] victim — first seen in simple_balance_transfer's program_output.pre_states
|
||||
// [2] recipient — first seen in simple_balance_transfer's program_output.pre_states
|
||||
//
|
||||
// Victim is marked Public: the attacker has no nsk for the victim's private account,
|
||||
// so PrivateAuthorizedUpdate is not an option.
|
||||
@ -833,7 +857,7 @@ mod tests {
|
||||
InputAccountIdentity::Public, // recipient
|
||||
];
|
||||
|
||||
// execute_and_prove succeeds: authenticated_transfer runs against the injected
|
||||
// execute_and_prove succeeds: simple_balance_transfer runs against the injected
|
||||
// victim(balance=5000, is_authorized=true) and produces valid inner receipts.
|
||||
// The outer circuit commits victim(is_authorized=true) to public_pre_states.
|
||||
let (circuit_output, proof) = execute_and_prove(
|
||||
@ -875,7 +899,7 @@ mod tests {
|
||||
/// Transaction (attacker signs) → P1 (`malicious_injector`)
|
||||
/// → injects `victim(is_authorized=true)` into chained-call `pre_states` for P2
|
||||
/// P2 (`malicious_launderer`)
|
||||
/// → outputs empty pre/post states, forwarding the forged flag to `authenticated_transfer`
|
||||
/// → outputs empty pre/post states, forwarding the forged flag to `simple_balance_transfer`
|
||||
/// → if `authorized_accounts` were built from the injected `pre_states`,
|
||||
/// `{victim}.contains(victim)` would pass and the transfer would execute.
|
||||
///
|
||||
@ -884,13 +908,13 @@ mod tests {
|
||||
/// input, so a forged `is_authorized=true` flag is never trusted.
|
||||
#[test]
|
||||
fn malicious_programs_cannot_drain_victim_without_signature() {
|
||||
// p2_id, auth_transfer_id, victim_id_raw, victim_balance, victim_nonce,
|
||||
// p2_id, simple_balance_transfer_id, victim_id_raw, victim_balance, victim_nonce,
|
||||
// victim_program_owner, recipient_id_raw, amount.
|
||||
// Primitives only — AccountId/Account cannot round-trip through instruction_data
|
||||
// via risc0_zkvm::serde (SerializeDisplay issue).
|
||||
type InjectorInstruction = (
|
||||
lee_core::program::ProgramId, // p2_id
|
||||
lee_core::program::ProgramId, // auth_transfer_id
|
||||
lee_core::program::ProgramId, // simple_balance_transfer_id
|
||||
[u8; 32], // victim_id_raw
|
||||
u128, // victim_balance
|
||||
u128, // victim_nonce
|
||||
@ -908,25 +932,24 @@ mod tests {
|
||||
let recipient_id = AccountId::new([42; 32]);
|
||||
|
||||
let victim_balance = 5_000_u128;
|
||||
let mut state = V03State::new_with_genesis_accounts(
|
||||
&[
|
||||
let state = V03State::new()
|
||||
.with_public_accounts(public_state_from_balances(&[
|
||||
(attacker_id, 100),
|
||||
(victim_id, victim_balance),
|
||||
(recipient_id, 0),
|
||||
],
|
||||
vec![],
|
||||
0,
|
||||
);
|
||||
|
||||
state.insert_program(Program::malicious_injector());
|
||||
state.insert_program(Program::malicious_launderer());
|
||||
]))
|
||||
.with_programs([
|
||||
crate::test_methods::simple_balance_transfer(),
|
||||
crate::test_methods::malicious_injector(),
|
||||
crate::test_methods::malicious_launderer(),
|
||||
]);
|
||||
|
||||
// Read victim state from chain, exactly as the attacker would.
|
||||
let victim_account = state.get_account_by_id(victim_id);
|
||||
|
||||
let instruction: InjectorInstruction = (
|
||||
Program::malicious_launderer().id(),
|
||||
Program::authenticated_transfer_program().id(),
|
||||
crate::test_methods::malicious_launderer().id(),
|
||||
crate::test_methods::simple_balance_transfer().id(),
|
||||
*victim_id.value(),
|
||||
victim_account.balance,
|
||||
victim_account.nonce.0,
|
||||
@ -936,7 +959,7 @@ mod tests {
|
||||
);
|
||||
|
||||
let message = Message::try_new(
|
||||
Program::malicious_injector().id(),
|
||||
crate::test_methods::malicious_injector().id(),
|
||||
vec![attacker_id],
|
||||
vec![Nonce(0)],
|
||||
instruction,
|
||||
@ -989,7 +1012,7 @@ mod tests {
|
||||
},
|
||||
};
|
||||
|
||||
let state = V03State::new_with_genesis_accounts(&[], vec![], 0);
|
||||
let state = V03State::new();
|
||||
|
||||
// Minimal message that passes every check up to proof verification: a single
|
||||
// commitment satisfies the non-empty requirement, no signers makes the
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "program_methods"
|
||||
name = "test_methods"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
license = { workspace = true }
|
||||
14
lee/state_machine/test_methods/guest/Cargo.toml
Normal file
14
lee/state_machine/test_methods/guest/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "test_methods_guests"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
license = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
lee_core.workspace = true
|
||||
|
||||
risc0-zkvm.workspace = true
|
||||
serde.workspace = true
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user