diff --git a/Cargo.lock b/Cargo.lock index c106d05d..391c9d69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1220,7 +1220,6 @@ dependencies = [ name = "bridge_program" version = "0.1.0" dependencies = [ - "authenticated_transfer_core", "bridge_core", "lee_core", "vault_core", @@ -3037,15 +3036,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared 0.1.1", -] - [[package]] name = "foreign-types" version = "0.5.0" @@ -3053,7 +3043,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared 0.3.1", + "foreign-types-shared", ] [[package]] @@ -3067,12 +3057,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "foreign-types-shared" version = "0.3.1" @@ -3852,22 +3836,6 @@ dependencies = [ "tower-service", ] -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - [[package]] name = "hyper-util" version = "0.1.20" @@ -3886,11 +3854,9 @@ dependencies = [ "percent-encoding", "pin-project-lite", "socket2 0.6.4", - "system-configuration 0.7.0", "tokio", "tower-service", "tracing", - "windows-registry", ] [[package]] @@ -4304,7 +4270,6 @@ dependencies = [ "anyhow", "associated_token_account_core", "authenticated_transfer_core", - "borsh", "bridge_core", "bridge_lock_core", "bytesize", @@ -4312,7 +4277,6 @@ dependencies = [ "cross_zone_inbox_core", "cross_zone_outbox_core", "faucet_core", - "futures", "hex", "indexer_ffi", "indexer_service_protocol", @@ -4322,12 +4286,9 @@ dependencies = [ "lee_core", "log", "logos-blockchain-core", - "logos-blockchain-http-api-common", "logos-blockchain-key-management-system-service", - "logos-blockchain-zone-sdk", "ping_core", "programs", - "reqwest", "risc0-zkvm", "sequencer_core", "sequencer_service_rpc", @@ -6676,7 +6637,7 @@ dependencies = [ "bitflags 2.12.1", "block", "core-graphics-types", - "foreign-types 0.5.0", + "foreign-types", "log", "objc", "paste", @@ -6839,23 +6800,6 @@ dependencies = [ "unsigned-varint 0.7.2", ] -[[package]] -name = "native-tls" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "natpmp" version = "0.5.0" @@ -7240,49 +7184,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "openssl" -version = "0.10.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" -dependencies = [ - "bitflags 2.12.1", - "cfg-if", - "foreign-types 0.3.2", - "libc", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - [[package]] name = "openssl-probe" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" -[[package]] -name = "openssl-sys" -version = "0.9.116" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "opentelemetry" version = "0.31.0" @@ -8440,7 +8347,6 @@ checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64 0.22.1", "bytes", - "encoding_rs", "futures-channel", "futures-core", "futures-util", @@ -8450,12 +8356,9 @@ dependencies = [ "http-body-util", "hyper", "hyper-rustls", - "hyper-tls", "hyper-util", "js-sys", "log", - "mime", - "native-tls", "percent-encoding", "pin-project-lite", "quinn", @@ -8466,7 +8369,6 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "tokio", - "tokio-native-tls", "tokio-rustls", "tokio-util", "tower", @@ -10537,16 +10439,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.26.4" diff --git a/integration_tests/Cargo.toml b/integration_tests/Cargo.toml index 957e00de..4d078550 100644 --- a/integration_tests/Cargo.toml +++ b/integration_tests/Cargo.toml @@ -38,16 +38,11 @@ programs.workspace = true test_programs.workspace = true testnet_initial_state.workspace = true -logos-blockchain-http-api-common.workspace = true logos-blockchain-core.workspace = true -logos-blockchain-zone-sdk.workspace = true logos-blockchain-key-management-system-service.workspace = true anyhow.workspace = true log.workspace = true tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } -futures.workspace = true hex.workspace = true tempfile.workspace = true bytesize.workspace = true -reqwest.workspace = true -borsh.workspace = true diff --git a/integration_tests/tests/bridge.rs b/integration_tests/tests/bridge.rs index e24cd69d..e980ffac 100644 --- a/integration_tests/tests/bridge.rs +++ b/integration_tests/tests/bridge.rs @@ -1,42 +1,23 @@ #![expect( clippy::tests_outside_test_module, - clippy::arithmetic_side_effects, reason = "We don't care about these in tests" )] -use std::{collections::HashSet, ops::Deref as _, time::Duration}; +use std::time::Duration; use anyhow::Context as _; -use borsh::BorshSerialize; use common::transaction::LeeTransaction; -use futures::StreamExt as _; use integration_tests::{ TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, account_balance, get_account, - wait_for_indexer_to_catch_up, }; use lee::{ - AccountId, execute_and_prove, privacy_preserving_transaction, program::Program, - public_transaction, + execute_and_prove, privacy_preserving_transaction, program::Program, public_transaction, }; use lee_core::{InputAccountIdentity, account::AccountWithMetadata}; -use log::info; -use logos_blockchain_core::mantle::{ledger::Inputs, ops::channel::deposit::DepositOp}; -use logos_blockchain_http_api_common::bodies::{ - channel::ChannelDepositRequestBody, - wallet::{ - balance::WalletBalanceResponseBody, - transfer_funds::{WalletTransferFundsRequestBody, WalletTransferFundsResponseBody}, - }, -}; -use logos_blockchain_zone_sdk::{ - CommonHttpClient, ZoneMessage, adapter::NodeHttpClient, indexer::ZoneIndexer, -}; use sequencer_service_rpc::RpcClient as _; -use test_fixtures::public_mention; use tokio::test; -use wallet::cli::{Command, execute_subcommand, programs::bridge::BridgeSubcommand}; -const TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK: Duration = Duration::from_mins(2); +// const TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK: Duration = Duration::from_mins(2); #[test] async fn public_bridge_deposit_invocation_is_dropped() -> anyhow::Result<()> { @@ -248,384 +229,386 @@ async fn private_bridge_deposit_invocation_is_dropped() -> anyhow::Result<()> { Ok(()) } -async fn submit_bedrock_deposit( - bedrock_addr: std::net::SocketAddr, - bedrock_account_pk: &str, - recipient_id: AccountId, - amount: u64, -) -> anyhow::Result<()> { - #[derive(BorshSerialize)] - struct DepositMetadata { - recipient_id: AccountId, - } +// async fn submit_bedrock_deposit( +// bedrock_addr: std::net::SocketAddr, +// bedrock_account_pk: &str, +// recipient_id: AccountId, +// amount: u64, +// ) -> anyhow::Result<()> { +// #[derive(BorshSerialize)] +// struct DepositMetadata { +// recipient_id: AccountId, +// } - // Encode deposit metadata - let metadata = borsh::to_vec(&DepositMetadata { recipient_id }) - .context("Failed to encode deposit metadata")? - .try_into() - .context("Encoded metadata is too big")?; +// // Encode deposit metadata +// let metadata = borsh::to_vec(&DepositMetadata { recipient_id }) +// .context("Failed to encode deposit metadata")? +// .try_into() +// .context("Encoded metadata is too big")?; - let channel_id = integration_tests::config::bedrock_channel_id(); - let client = reqwest::Client::new(); +// let channel_id = integration_tests::config::bedrock_channel_id(); +// let client = reqwest::Client::new(); - let mut balance = bedrock_wallet_balance(bedrock_addr, bedrock_account_pk).await?; +// let mut balance = bedrock_wallet_balance(bedrock_addr, bedrock_account_pk).await?; - info!( - "Queried Bedrock balance for key {bedrock_account_pk}: {:?}", - balance.balance - ); +// info!( +// "Queried Bedrock balance for key {bedrock_account_pk}: {:?}", +// balance.balance +// ); - if balance.balance < amount { - anyhow::bail!( - "Bedrock wallet with key {bedrock_account_pk} has insufficient balance {:?} for deposit amount {:?}", - balance.balance, - amount - ); - } +// if balance.balance < amount { +// anyhow::bail!( +// "Bedrock wallet with key {bedrock_account_pk} has insufficient balance {:?} for +// deposit amount {:?}", balance.balance, +// amount +// ); +// } - let mut selected_note_id = balance - .notes - .iter() - .find_map(|(note_id, value)| (*value == amount).then_some(*note_id)); +// let mut selected_note_id = balance +// .notes +// .iter() +// .find_map(|(note_id, value)| (*value == amount).then_some(*note_id)); - if selected_note_id.is_none() { - let transfer_body = WalletTransferFundsRequestBody { - tip: None, - change_public_key: balance.address, - funding_public_keys: vec![balance.address], - recipient_public_key: balance.address, - amount, - }; +// if selected_note_id.is_none() { +// let transfer_body = WalletTransferFundsRequestBody { +// tip: None, +// change_public_key: balance.address, +// funding_public_keys: vec![balance.address], +// recipient_public_key: balance.address, +// amount, +// }; - let transfer_response = client - .post(format!( - "http://{bedrock_addr}/wallet/transactions/transfer-funds" - )) - .json(&transfer_body) - .send() - .await - .context("Failed to submit Bedrock transfer-funds request")?; - let transfer_response = check_response_success(transfer_response).await?; +// let transfer_response = client +// .post(format!( +// "http://{bedrock_addr}/wallet/transactions/transfer-funds" +// )) +// .json(&transfer_body) +// .send() +// .await +// .context("Failed to submit Bedrock transfer-funds request")?; +// let transfer_response = check_response_success(transfer_response).await?; - let transfer: WalletTransferFundsResponseBody = transfer_response - .json() - .await - .context("Failed to decode Bedrock transfer-funds response")?; +// let transfer: WalletTransferFundsResponseBody = transfer_response +// .json() +// .await +// .context("Failed to decode Bedrock transfer-funds response")?; - info!( - "Submitted transfer-funds to create exact deposit note, tx hash {:?}", - transfer.hash - ); +// info!( +// "Submitted transfer-funds to create exact deposit note, tx hash {:?}", +// transfer.hash +// ); - let mut found_note = None; - for _ in 0..20 { - tokio::time::sleep(Duration::from_millis(500)).await; - balance = bedrock_wallet_balance(bedrock_addr, bedrock_account_pk).await?; - found_note = balance - .notes - .iter() - .find_map(|(note_id, value)| (*value == amount).then_some(*note_id)); - if found_note.is_some() { - break; - } - } +// let mut found_note = None; +// for _ in 0..20 { +// tokio::time::sleep(Duration::from_millis(500)).await; +// balance = bedrock_wallet_balance(bedrock_addr, bedrock_account_pk).await?; +// found_note = balance +// .notes +// .iter() +// .find_map(|(note_id, value)| (*value == amount).then_some(*note_id)); +// if found_note.is_some() { +// break; +// } +// } - selected_note_id = found_note; - } +// selected_note_id = found_note; +// } - let Some(selected_note_id) = selected_note_id else { - anyhow::bail!( - "Failed to locate exact-value note {amount:?} for Bedrock deposit; available notes: {:?}", - balance.notes, - ); - }; +// let Some(selected_note_id) = selected_note_id else { +// anyhow::bail!( +// "Failed to locate exact-value note {amount:?} for Bedrock deposit; available notes: +// {:?}", balance.notes, +// ); +// }; - let body = ChannelDepositRequestBody { - tip: None, - deposit: DepositOp { - channel_id, - inputs: Inputs::new(selected_note_id), - metadata, - }, - change_public_key: balance.address, - funding_public_keys: vec![balance.address], - max_tx_fee: u64::MAX.into(), - }; +// let body = ChannelDepositRequestBody { +// tip: None, +// deposit: DepositOp { +// channel_id, +// inputs: Inputs::new(selected_note_id), +// metadata, +// }, +// change_public_key: balance.address, +// funding_public_keys: vec![balance.address], +// max_tx_fee: u64::MAX.into(), +// }; - let response = client - .post(format!("http://{bedrock_addr}/channel/deposit")) - .json(&body) - .send() - .await - .context("Failed to submit Bedrock deposit request")?; - let response = check_response_success(response).await?; +// let response = client +// .post(format!("http://{bedrock_addr}/channel/deposit")) +// .json(&body) +// .send() +// .await +// .context("Failed to submit Bedrock deposit request")?; +// let response = check_response_success(response).await?; - let body_text = response - .text() - .await - .unwrap_or_else(|_| "".to_owned()); - info!( - "Successfully submitted Bedrock deposit request for recipient {recipient_id} and amount {amount}, response body: {body_text}", - ); +// let body_text = response +// .text() +// .await +// .unwrap_or_else(|_| "".to_owned()); +// info!( +// "Successfully submitted Bedrock deposit request for recipient {recipient_id} and amount +// {amount}, response body: {body_text}", ); - Ok(()) -} +// Ok(()) +// } -/// The Bedrock wallet state of `bedrock_account_pk`: its total balance and the -/// notes it owns, keyed by note id. -async fn bedrock_wallet_balance( - bedrock_addr: std::net::SocketAddr, - bedrock_account_pk: &str, -) -> anyhow::Result { - let response = reqwest::Client::new() - .get(format!( - "http://{bedrock_addr}/wallet/{bedrock_account_pk}/balance" - )) - .send() - .await - .context("Failed to query Bedrock wallet balance")?; +// /// The Bedrock wallet state of `bedrock_account_pk`: its total balance and the +// /// notes it owns, keyed by note id. +// async fn bedrock_wallet_balance( +// bedrock_addr: std::net::SocketAddr, +// bedrock_account_pk: &str, +// ) -> anyhow::Result { +// let response = reqwest::Client::new() +// .get(format!( +// "http://{bedrock_addr}/wallet/{bedrock_account_pk}/balance" +// )) +// .send() +// .await +// .context("Failed to query Bedrock wallet balance")?; - check_response_success(response) - .await? - .json::() - .await - .context("Failed to decode Bedrock balance response") -} +// check_response_success(response) +// .await? +// .json::() +// .await +// .context("Failed to decode Bedrock balance response") +// } -async fn check_response_success(response: reqwest::Response) -> anyhow::Result { - if response.status().is_success() { - Ok(response) - } else { - let status = response.status(); - let body_text = response.text().await.unwrap_or_default(); - anyhow::bail!("Request failed with status {status} and body {body_text}"); - } -} +// async fn check_response_success(response: reqwest::Response) -> anyhow::Result +// { if response.status().is_success() { +// Ok(response) +// } else { +// let status = response.status(); +// let body_text = response.text().await.unwrap_or_default(); +// anyhow::bail!("Request failed with status {status} and body {body_text}"); +// } +// } -async fn wait_for_vault_balance( - ctx: &TestContext, - vault_id: AccountId, - expected_balance: u128, -) -> anyhow::Result<()> { - let timeout = TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK - + Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS); - tokio::time::timeout(timeout, async { - loop { - let balance = account_balance(ctx, vault_id).await?; - if balance == expected_balance { - return Ok(()); - } - tokio::time::sleep(Duration::from_millis(500)).await; - } - }) - .await - .with_context(|| { - format!("Timed out waiting for vault {vault_id} balance to reach {expected_balance}") - })? -} +// async fn wait_for_vault_balance( +// ctx: &TestContext, +// vault_id: AccountId, +// expected_balance: u128, +// ) -> anyhow::Result<()> { +// let timeout = TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK +// + Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS); +// tokio::time::timeout(timeout, async { +// loop { +// let balance = account_balance(ctx, vault_id).await?; +// if balance == expected_balance { +// return Ok(()); +// } +// tokio::time::sleep(Duration::from_millis(500)).await; +// } +// }) +// .await +// .with_context(|| { +// format!("Timed out waiting for vault {vault_id} balance to reach {expected_balance}") +// })? +// } -/// Test deposit and withdraw round trip. -/// -/// Implemented as one test instead of two separate tests for deposit and withdraw, because the -/// withdraw test depends on the deposit to set up the necessary state (funds in vault) for testing -/// withdraw functionality. -#[test] -async fn bedrock_deposit_claim_and_withdraw_round_trip_succeeds() -> anyhow::Result<()> { - let mut ctx = TestContext::new().await?; +// /// Test deposit and withdraw round trip. +// /// +// /// Implemented as one test instead of two separate tests for deposit and withdraw, because the +// /// withdraw test depends on the deposit to set up the necessary state (funds in vault) for +// testing /// withdraw functionality. +// #[test] +// async fn bedrock_deposit_claim_and_withdraw_round_trip_succeeds() -> anyhow::Result<()> { +// let mut ctx = TestContext::new().await?; - let bedrock_account_pk = "2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26"; - let recipient_id = ctx.existing_public_accounts()[0]; - let amount = 1_u64; - let vault_program_id = programs::vault().id(); - let recipient_vault_id = vault_core::compute_vault_account_id(vault_program_id, recipient_id); +// let bedrock_account_pk = "2e03b2eff5a45478e7e79668d2a146cf2c5c7925bce927f2b1c67f2ab4fc0d26"; +// let recipient_id = ctx.existing_public_accounts()[0]; +// let amount = 1_u64; +// 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 = account_balance(&ctx, recipient_vault_id).await?; - let recipient_balance_before = account_balance(&ctx, recipient_id).await?; +// let vault_balance_before = account_balance(&ctx, recipient_vault_id).await?; +// let recipient_balance_before = account_balance(&ctx, recipient_id).await?; - // Submit deposit to Bedrock - submit_bedrock_deposit(ctx.bedrock_addr(), bedrock_account_pk, recipient_id, amount) - .await - .context("Failed to submit Bedrock deposit for round-trip setup")?; +// // Submit deposit to Bedrock +// submit_bedrock_deposit(ctx.bedrock_addr(), bedrock_account_pk, recipient_id, amount) +// .await +// .context("Failed to submit Bedrock deposit for round-trip setup")?; - // Wait for vault to receive the deposit (minted from bridge to vault) - wait_for_vault_balance( - &ctx, - recipient_vault_id, - vault_balance_before + u128::from(amount), - ) - .await?; +// // Wait for vault to receive the deposit (minted from bridge to vault) +// wait_for_vault_balance( +// &ctx, +// recipient_vault_id, +// vault_balance_before + u128::from(amount), +// ) +// .await?; - // Now claim funds from vault back to recipient - let nonces = ctx - .wallet() - .get_accounts_nonces(&[recipient_id]) - .await - .context("Failed to get nonce for vault claim")?; +// // Now claim funds from vault back to recipient +// let nonces = ctx +// .wallet() +// .get_accounts_nonces(&[recipient_id]) +// .await +// .context("Failed to get nonce for vault claim")?; - let signing_key = ctx - .wallet() - .storage() - .key_chain() - .pub_account_signing_key(recipient_id) - .with_context(|| format!("Missing signing key for account {recipient_id}"))?; +// let signing_key = ctx +// .wallet() +// .storage() +// .key_chain() +// .pub_account_signing_key(recipient_id) +// .with_context(|| format!("Missing signing key for account {recipient_id}"))?; - let claim_message = public_transaction::Message::try_new( - vault_program_id, - vec![recipient_id, recipient_vault_id], - nonces, - vault_core::Instruction::Claim { - amount: u128::from(amount), - }, - ) - .context("Failed to build vault claim message")?; +// let claim_message = public_transaction::Message::try_new( +// vault_program_id, +// vec![recipient_id, recipient_vault_id], +// nonces, +// vault_core::Instruction::Claim { +// amount: u128::from(amount), +// }, +// ) +// .context("Failed to build vault claim message")?; - let claim_witness_set = - public_transaction::WitnessSet::for_message(&claim_message, &[signing_key]); - let claim_tx = LeeTransaction::Public(lee::PublicTransaction::new( - claim_message, - claim_witness_set, - )); +// let claim_witness_set = +// public_transaction::WitnessSet::for_message(&claim_message, &[signing_key]); +// let claim_tx = LeeTransaction::Public(lee::PublicTransaction::new( +// claim_message, +// claim_witness_set, +// )); - let claim_hash = ctx.sequencer_client().send_transaction(claim_tx).await?; +// let claim_hash = ctx.sequencer_client().send_transaction(claim_tx).await?; - tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; +// tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; - let claim_on_chain = ctx.sequencer_client().get_transaction(claim_hash).await?; - let vault_balance_after_claim = account_balance(&ctx, recipient_vault_id).await?; - let recipient_balance_after_claim = account_balance(&ctx, recipient_id).await?; +// let claim_on_chain = ctx.sequencer_client().get_transaction(claim_hash).await?; +// let vault_balance_after_claim = account_balance(&ctx, recipient_vault_id).await?; +// let recipient_balance_after_claim = account_balance(&ctx, recipient_id).await?; - assert!( - claim_on_chain.is_some(), - "Vault claim transaction must be included on-chain" - ); - assert_eq!( - vault_balance_after_claim, vault_balance_before, - "Vault balance should return to initial state after claim" - ); - assert_eq!( - recipient_balance_after_claim, - recipient_balance_before + u128::from(amount), - "Recipient balance should increase by claimed amount" - ); +// assert!( +// claim_on_chain.is_some(), +// "Vault claim transaction must be included on-chain" +// ); +// assert_eq!( +// vault_balance_after_claim, vault_balance_before, +// "Vault balance should return to initial state after claim" +// ); +// assert_eq!( +// recipient_balance_after_claim, +// recipient_balance_before + u128::from(amount), +// "Recipient balance should increase by claimed amount" +// ); - // The indexer must replay the deposit and claim blocks and reach the same - // 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 = 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 - // of the async `get_account` method on `RpcClient` - ctx.indexer_client().deref(), - account_id.into(), - ) - .await?; - let sequencer_account = get_account(&ctx, account_id).await?; - assert_eq!( - indexer_account, - sequencer_account.into(), - "Indexer and sequencer diverged for account {account_id} after deposit" - ); - } +// // The indexer must replay the deposit and claim blocks and reach the same +// // 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 = 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 +// // of the async `get_account` method on `RpcClient` +// ctx.indexer_client().deref(), +// account_id.into(), +// ) +// .await?; +// let sequencer_account = get_account(&ctx, account_id).await?; +// assert_eq!( +// indexer_account, +// sequencer_account.into(), +// "Indexer and sequencer diverged for account {account_id} after deposit" +// ); +// } - // Withdraw back to Bedrock and wait for finalized withdraw event. - let sender_id = recipient_id; +// // Withdraw back to Bedrock and wait for finalized withdraw event. +// let sender_id = recipient_id; - let observer = create_zone_indexer_observer(ctx.bedrock_addr())?; - let observe_fut = - wait_for_finalized_withdraw_op(&observer, ctx.bedrock_addr(), amount, bedrock_account_pk); +// let observer = create_zone_indexer_observer(ctx.bedrock_addr())?; +// let observe_fut = +// wait_for_finalized_withdraw_op(&observer, ctx.bedrock_addr(), amount, +// bedrock_account_pk); - let withdraw_fut = execute_subcommand( - ctx.wallet_mut(), - Command::Bridge(BridgeSubcommand::Withdraw { - from: public_mention(sender_id), - amount, - bedrock_account_pk: bedrock_account_pk.to_owned(), - }), - ); +// let withdraw_fut = execute_subcommand( +// ctx.wallet_mut(), +// Command::Bridge(BridgeSubcommand::Withdraw { +// from: public_mention(sender_id), +// amount, +// bedrock_account_pk: bedrock_account_pk.to_owned(), +// }), +// ); - let (observe_result, withdraw_result) = tokio::join!(observe_fut, withdraw_fut); +// let (observe_result, withdraw_result) = tokio::join!(observe_fut, withdraw_fut); - withdraw_result.context("Failed to execute wallet bridge withdraw command")?; +// withdraw_result.context("Failed to execute wallet bridge withdraw command")?; - observe_result - .context("Failed while waiting for finalized withdraw event from zone indexer")?; +// observe_result +// .context("Failed while waiting for finalized withdraw event from zone indexer")?; - // Sleep to observe sequencer log about validated withdraw event - tokio::time::sleep(Duration::from_secs(1)).await; +// // Sleep to observe sequencer log about validated withdraw event +// tokio::time::sleep(Duration::from_secs(1)).await; - Ok(()) -} +// Ok(()) +// } -fn create_zone_indexer_observer( - bedrock_addr: std::net::SocketAddr, -) -> anyhow::Result> { - let bedrock_url = integration_tests::config::addr_to_url( - integration_tests::config::UrlProtocol::Http, - bedrock_addr, - ) - .context("Failed to convert Bedrock addr to URL for zone indexer observer")?; +// fn create_zone_indexer_observer( +// bedrock_addr: std::net::SocketAddr, +// ) -> anyhow::Result> { +// let bedrock_url = integration_tests::config::addr_to_url( +// integration_tests::config::UrlProtocol::Http, +// bedrock_addr, +// ) +// .context("Failed to convert Bedrock addr to URL for zone indexer observer")?; - let node = NodeHttpClient::new(CommonHttpClient::new(None), bedrock_url); +// let node = NodeHttpClient::new(CommonHttpClient::new(None), bedrock_url); - Ok(ZoneIndexer::new( - integration_tests::config::bedrock_channel_id(), - node, - )) -} +// Ok(ZoneIndexer::new( +// integration_tests::config::bedrock_channel_id(), +// node, +// )) +// } -/// Waits for a finalized withdraw that pays `expected_amount` to `receiver_pk`. -/// -/// A withdraw op releases channel-owned notes and carries nothing but their -/// ids — the value and recipient live in the note itself. A released note keeps -/// its id, value and public key, so the pairing is checked on the receiver's -/// Bedrock wallet: one of the released notes must land there with the expected -/// value. -async fn wait_for_finalized_withdraw_op( - observer: &ZoneIndexer, - bedrock_addr: std::net::SocketAddr, - expected_amount: u64, - receiver_pk: &str, -) -> anyhow::Result<()> { - let timeout = TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK - + Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS); +// /// Waits for a finalized withdraw that pays `expected_amount` to `receiver_pk`. +// /// +// /// A withdraw op releases channel-owned notes and carries nothing but their +// /// ids — the value and recipient live in the note itself. A released note keeps +// /// its id, value and public key, so the pairing is checked on the receiver's +// /// Bedrock wallet: one of the released notes must land there with the expected +// /// value. +// async fn wait_for_finalized_withdraw_op( +// observer: &ZoneIndexer, +// bedrock_addr: std::net::SocketAddr, +// expected_amount: u64, +// receiver_pk: &str, +// ) -> anyhow::Result<()> { +// let timeout = TIME_TO_FINALIZE_DEPOSIT_EVENT_ON_BEDROCK +// + Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS); - tokio::time::timeout(timeout, async { - // The wallet can trail the channel event, so released notes accumulate - // across polls instead of being checked once when first observed. - let mut released_notes = HashSet::new(); +// tokio::time::timeout(timeout, async { +// // The wallet can trail the channel event, so released notes accumulate +// // across polls instead of being checked once when first observed. +// let mut released_notes = HashSet::new(); - loop { - let stream = observer - .follow() - .await - .context("Failed to read zone indexer message batch")?; - let mut stream = std::pin::pin!(stream); +// loop { +// let stream = observer +// .follow() +// .await +// .context("Failed to read zone indexer message batch")?; +// let mut stream = std::pin::pin!(stream); - while let Some(message) = stream.next().await { - info!("Observed zone message {message:?}"); +// while let Some(message) = stream.next().await { +// info!("Observed zone message {message:?}"); - if let ZoneMessage::Withdraw(withdraw) = message { - released_notes.extend(withdraw.inputs.iter().copied()); - } - } +// if let ZoneMessage::Withdraw(withdraw) = message { +// released_notes.extend(withdraw.inputs.iter().copied()); +// } +// } - if !released_notes.is_empty() { - let balance = bedrock_wallet_balance(bedrock_addr, receiver_pk).await?; - if released_notes - .iter() - .any(|note_id| balance.notes.get(note_id) == Some(&expected_amount)) - { - return Ok(()); - } - } +// if !released_notes.is_empty() { +// let balance = bedrock_wallet_balance(bedrock_addr, receiver_pk).await?; +// if released_notes +// .iter() +// .any(|note_id| balance.notes.get(note_id) == Some(&expected_amount)) +// { +// return Ok(()); +// } +// } - tokio::time::sleep(Duration::from_millis(500)).await; - } - }) - .await - .with_context(|| { - format!("Timed out waiting for finalized withdraw message with amount {expected_amount}") - })? -} +// tokio::time::sleep(Duration::from_millis(500)).await; +// } +// }) +// .await +// .with_context(|| { +// format!("Timed out waiting for finalized withdraw message with amount {expected_amount}") +// })? +// } diff --git a/integration_tests/tests/wallet_ffi.rs b/integration_tests/tests/wallet_ffi.rs index a36eb069..a19bc355 100644 --- a/integration_tests/tests/wallet_ffi.rs +++ b/integration_tests/tests/wallet_ffi.rs @@ -170,13 +170,13 @@ unsafe extern "C" { fn wallet_ffi_free_transfer_result(result: *mut FfiTransferResult); - fn wallet_ffi_bridge_withdraw( - handle: *mut WalletHandle, - from: *const FfiBytes32, - amount: u64, - bedrock_account_pk: *const FfiBytes32, - out_result: *mut FfiTransferResult, - ) -> error::WalletFfiError; + // fn wallet_ffi_bridge_withdraw( + // handle: *mut WalletHandle, + // from: *const FfiBytes32, + // amount: u64, + // bedrock_account_pk: *const FfiBytes32, + // out_result: *mut FfiTransferResult, + // ) -> error::WalletFfiError; fn wallet_ffi_get_vault_balance( handle: *mut WalletHandle, @@ -1521,68 +1521,68 @@ fn restore_keys_from_seed_ffi() -> Result<()> { Ok(()) } -#[test] -fn test_wallet_ffi_bridge_withdraw() -> Result<()> { - let ctx = BlockingTestContext::new()?; - let home = tempfile::tempdir()?; - let FfiCreateWalletOutput { - wallet: wallet_ffi_handle, - 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 = system_accounts::bridge_account_id().into(); - let bedrock_account_pk = FfiBytes32::from_bytes([0x42; 32]); - let amount = 100_u64; +// #[test] +// fn test_wallet_ffi_bridge_withdraw() -> Result<()> { +// let ctx = BlockingTestContext::new()?; +// let home = tempfile::tempdir()?; +// let FfiCreateWalletOutput { +// wallet: wallet_ffi_handle, +// 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 = system_accounts::bridge_account_id().into(); +// let bedrock_account_pk = FfiBytes32::from_bytes([0x42; 32]); +// let amount = 100_u64; - let mut transfer_result = FfiTransferResult::default(); - unsafe { - wallet_ffi_bridge_withdraw( - wallet_ffi_handle, - &raw const from, - amount, - &raw const bedrock_account_pk, - &raw mut transfer_result, - ) - .unwrap(); - } +// let mut transfer_result = FfiTransferResult::default(); +// unsafe { +// wallet_ffi_bridge_withdraw( +// wallet_ffi_handle, +// &raw const from, +// amount, +// &raw const bedrock_account_pk, +// &raw mut transfer_result, +// ) +// .unwrap(); +// } - info!("Waiting for next block creation"); - std::thread::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)); +// info!("Waiting for next block creation"); +// std::thread::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)); - let from_balance = unsafe { - let mut out_balance: [u8; 16] = [0; 16]; - wallet_ffi_get_balance( - wallet_ffi_handle, - &raw const from, - true, - &raw mut out_balance, - ) - .unwrap(); - u128::from_le_bytes(out_balance) - }; +// let from_balance = unsafe { +// let mut out_balance: [u8; 16] = [0; 16]; +// wallet_ffi_get_balance( +// wallet_ffi_handle, +// &raw const from, +// true, +// &raw mut out_balance, +// ) +// .unwrap(); +// u128::from_le_bytes(out_balance) +// }; - let bridge_balance = unsafe { - let mut out_balance: [u8; 16] = [0; 16]; - wallet_ffi_get_balance( - wallet_ffi_handle, - &raw const bridge_account, - true, - &raw mut out_balance, - ) - .unwrap(); - u128::from_le_bytes(out_balance) - }; +// let bridge_balance = unsafe { +// let mut out_balance: [u8; 16] = [0; 16]; +// wallet_ffi_get_balance( +// wallet_ffi_handle, +// &raw const bridge_account, +// true, +// &raw mut out_balance, +// ) +// .unwrap(); +// u128::from_le_bytes(out_balance) +// }; - assert_eq!(from_balance, 9900); - assert_eq!(bridge_balance, 1_000_100); +// assert_eq!(from_balance, 9900); +// assert_eq!(bridge_balance, 1_000_100); - unsafe { - wallet_ffi_free_transfer_result(&raw mut transfer_result); - wallet_ffi_destroy(wallet_ffi_handle); - } +// unsafe { +// wallet_ffi_free_transfer_result(&raw mut transfer_result); +// wallet_ffi_destroy(wallet_ffi_handle); +// } - Ok(()) -} +// Ok(()) +// } #[test] fn test_wallet_ffi_transfer_generic_public() -> Result<()> { diff --git a/lez/programs/bridge/Cargo.toml b/lez/programs/bridge/Cargo.toml index d7762f1f..1241adde 100644 --- a/lez/programs/bridge/Cargo.toml +++ b/lez/programs/bridge/Cargo.toml @@ -7,5 +7,4 @@ license = { workspace = true } [dependencies] bridge_core.workspace = true vault_core.workspace = true -authenticated_transfer_core.workspace = true lee_core.workspace = true diff --git a/lez/programs/bridge/src/main.rs b/lez/programs/bridge/src/main.rs index c42149da..1fd3333a 100644 --- a/lez/programs/bridge/src/main.rs +++ b/lez/programs/bridge/src/main.rs @@ -104,33 +104,35 @@ fn main() { } } Instruction::Withdraw { - amount, + amount: _, bedrock_account_pk: _, } => { - let [sender, bridge] = pre_states - .try_into() - .expect("Withdraw requires exactly 2 accounts"); + panic!("Withdraws are disabled in the current version of LEZ"); - assert_eq!( - bridge.account_id, - bridge_core::compute_bridge_account_id(self_program_id), - "Second account must be bridge PDA" - ); + // let [sender, bridge] = pre_states + // .try_into() + // .expect("Withdraw requires exactly 2 accounts"); - let auth_transfer_program_id = bridge.account.program_owner; - assert_eq!( - sender.account.program_owner, auth_transfer_program_id, - "Sender account must be owned by the authenticated transfer program" - ); + // assert_eq!( + // bridge.account_id, + // bridge_core::compute_bridge_account_id(self_program_id), + // "Second account must be bridge PDA" + // ); - let chained_calls = vec![ChainedCall::new( - auth_transfer_program_id, - vec![sender, bridge], - &authenticated_transfer_core::Instruction::Transfer { - amount: u128::from(amount), - }, - )]; - (unchanged_post_states(&pre_states_clone), chained_calls) + // let auth_transfer_program_id = bridge.account.program_owner; + // assert_eq!( + // sender.account.program_owner, auth_transfer_program_id, + // "Sender account must be owned by the authenticated transfer program" + // ); + + // let chained_calls = vec![ChainedCall::new( + // auth_transfer_program_id, + // vec![sender, bridge], + // &authenticated_transfer_core::Instruction::Transfer { + // amount: u128::from(amount), + // }, + // )]; + // (unchanged_post_states(&pre_states_clone), chained_calls) } }; diff --git a/lez/sequencer/core/src/tests.rs b/lez/sequencer/core/src/tests.rs index d2695546..d5a18ac6 100644 --- a/lez/sequencer/core/src/tests.rs +++ b/lez/sequencer/core/src/tests.rs @@ -8,20 +8,10 @@ use common::{ test_utils::sequencer_sign_key_for_testing, transaction::{LeeTransaction, clock_invocation}, }; -use key_protocol::key_management::KeyChain; use lee::{ - Account, AccountId, Data, PrivacyPreservingTransaction, PrivateKey, PublicKey, - PublicTransaction, V03State, - error::LeeError, - execute_and_prove, - privacy_preserving_transaction::{Message, circuit::ProgramWithDependencies}, - program::Program, -}; -use lee_core::{ - Commitment, InputAccountIdentity, Nullifier, - account::{AccountWithMetadata, Nonce}, - program::PdaSeed, + Account, AccountId, Data, PrivateKey, PublicKey, PublicTransaction, V03State, program::Program, }; +use lee_core::{account::Nonce, program::PdaSeed}; use logos_blockchain_core::{ events::DepositRecreatedNotes, mantle::{ @@ -1479,94 +1469,94 @@ async fn block_production_aborts_when_clock_account_data_is_corrupted() { ); } -#[test] -fn private_bridge_withdraw_invocation_is_dropped() { - let sender_keys = KeyChain::new_os_random(); - let sender_account_id = AccountId::for_regular_private_account( - &sender_keys.nullifier_public_key, - &sender_keys.viewing_public_key, - 0, - ); - let sender_private_account = Account { - program_owner: programs::authenticated_transfer().id(), - balance: 100, - nonce: Nonce(0xdead_beef), - data: Data::default(), - }; - let bridge_account_id = system_accounts::bridge_account_id(); +// #[test] +// fn private_bridge_withdraw_invocation_is_dropped() { +// let sender_keys = KeyChain::new_os_random(); +// let sender_account_id = AccountId::for_regular_private_account( +// &sender_keys.nullifier_public_key, +// &sender_keys.viewing_public_key, +// 0, +// ); +// let sender_private_account = Account { +// program_owner: programs::authenticated_transfer().id(), +// balance: 100, +// nonce: Nonce(0xdead_beef), +// data: Data::default(), +// }; +// let bridge_account_id = system_accounts::bridge_account_id(); - let mut state = V03State::new() - .with_public_accounts([(bridge_account_id, system_accounts::bridge_account())]) - .with_private_accounts([( - Commitment::new(&sender_account_id, &sender_private_account), - Nullifier::for_account_initialization(&sender_account_id), - )]); +// let mut state = V03State::new() +// .with_public_accounts([(bridge_account_id, system_accounts::bridge_account())]) +// .with_private_accounts([( +// Commitment::new(&sender_account_id, &sender_private_account), +// Nullifier::for_account_initialization(&sender_account_id), +// )]); - let sender_commitment = Commitment::new(&sender_account_id, &sender_private_account); +// let sender_commitment = Commitment::new(&sender_account_id, &sender_private_account); - let sender_pre = AccountWithMetadata::new( - sender_private_account, - true, - ( - &sender_keys.nullifier_public_key, - &sender_keys.viewing_public_key, - 0, - ), - ); - let bridge_pre = AccountWithMetadata::new( - state.get_account_by_id(bridge_account_id), - false, - bridge_account_id, - ); +// let sender_pre = AccountWithMetadata::new( +// sender_private_account, +// true, +// ( +// &sender_keys.nullifier_public_key, +// &sender_keys.viewing_public_key, +// 0, +// ), +// ); +// let bridge_pre = AccountWithMetadata::new( +// state.get_account_by_id(bridge_account_id), +// false, +// bridge_account_id, +// ); - let instruction = Program::serialize_instruction(bridge_core::Instruction::Withdraw { - amount: 1, - bedrock_account_pk: [0; 32], - }) - .unwrap(); +// let instruction = Program::serialize_instruction(bridge_core::Instruction::Withdraw { +// amount: 1, +// bedrock_account_pk: [0; 32], +// }) +// .unwrap(); - let program_with_deps = ProgramWithDependencies::new( - programs::bridge(), - [( - programs::authenticated_transfer().id(), - programs::authenticated_transfer(), - )] - .into(), - ); +// let program_with_deps = ProgramWithDependencies::new( +// programs::bridge(), +// [( +// programs::authenticated_transfer().id(), +// programs::authenticated_transfer(), +// )] +// .into(), +// ); - let (output, proof) = execute_and_prove( - vec![sender_pre, bridge_pre], - instruction, - vec![ - InputAccountIdentity::PrivateAuthorizedUpdate { - vpk: sender_keys.viewing_public_key.clone(), - random_seed: [0; 32], - view_tag: 0, - nsk: sender_keys.private_key_holder.nullifier_secret_key, - membership_proof: state - .get_proof_for_commitment(&sender_commitment) - .expect("sender commitment must be in state"), - identifier: 0, - }, - InputAccountIdentity::Public, - ], - &program_with_deps, - ) - .expect("Execution should succeed"); +// let (output, proof) = execute_and_prove( +// vec![sender_pre, bridge_pre], +// instruction, +// vec![ +// InputAccountIdentity::PrivateAuthorizedUpdate { +// vpk: sender_keys.viewing_public_key.clone(), +// random_seed: [0; 32], +// view_tag: 0, +// nsk: sender_keys.private_key_holder.nullifier_secret_key, +// membership_proof: state +// .get_proof_for_commitment(&sender_commitment) +// .expect("sender commitment must be in state"), +// identifier: 0, +// }, +// InputAccountIdentity::Public, +// ], +// &program_with_deps, +// ) +// .expect("Execution should succeed"); - let message = Message::try_from_circuit_output(vec![bridge_account_id], vec![], output) - .expect("Message construction should succeed"); - let witness_set = - lee::privacy_preserving_transaction::WitnessSet::for_message(&message, proof, &[]); - let tx = - LeeTransaction::PrivacyPreserving(PrivacyPreservingTransaction::new(message, witness_set)); - let res = tx.execute_check_on_state(&mut state, 1, 0); +// let message = Message::try_from_circuit_output(vec![bridge_account_id], vec![], output) +// .expect("Message construction should succeed"); +// let witness_set = +// lee::privacy_preserving_transaction::WitnessSet::for_message(&message, proof, &[]); +// let tx = +// LeeTransaction::PrivacyPreserving(PrivacyPreservingTransaction::new(message, +// witness_set)); let res = tx.execute_check_on_state(&mut state, 1, 0); - assert!( - matches!(res, Err(LeeError::InvalidInput(_))), - "Bridge withdraw invocation should be rejected in private execution" - ); -} +// assert!( +// matches!(res, Err(LeeError::InvalidInput(_))), +// "Bridge withdraw invocation should be rejected in private execution" +// ); +// } /// Builds a [`V03State`] with the clock program and `program` registered, the three clock /// accounts initialized, and the clock advanced to `clock_timestamp` so that reads of the diff --git a/lez/sequencer/core/src/tests/reconstruction.rs b/lez/sequencer/core/src/tests/reconstruction.rs index 8c48a054..846abe20 100644 --- a/lez/sequencer/core/src/tests/reconstruction.rs +++ b/lez/sequencer/core/src/tests/reconstruction.rs @@ -10,7 +10,7 @@ use chain_state::ChainState; use common::block::Block; use logos_blockchain_core::mantle::ops::channel::{MsgId, inscribe::Inscription}; use logos_blockchain_zone_sdk::{Slot, ZoneBlock, ZoneMessage}; -use storage::sequencer::sequencer_cells::{WithdrawalReconciliationKey, ZoneAnchorRecord}; +use storage::sequencer::sequencer_cells::ZoneAnchorRecord; use super::*; use crate::{ @@ -298,229 +298,230 @@ fn deposit_event_record( } } -/// Builds a signed public bridge `Withdraw` transaction (the normal user path). -fn build_public_withdraw_tx( - sender: lee::AccountId, - nonce: u128, - amount: u64, - bedrock_account_pk: [u8; 32], - signing_key: &lee::PrivateKey, -) -> LeeTransaction { - let message = lee::public_transaction::Message::try_new( - programs::bridge().id(), - vec![sender, system_accounts::bridge_account_id()], - vec![nonce.into()], - bridge_core::Instruction::Withdraw { - amount, - bedrock_account_pk, - }, - ) - .unwrap(); - let witness_set = lee::public_transaction::WitnessSet::for_message(&message, &[signing_key]); - LeeTransaction::Public(lee::PublicTransaction::new(message, witness_set)) -} +// /// Builds a signed public bridge `Withdraw` transaction (the normal user path). +// fn build_public_withdraw_tx( +// sender: lee::AccountId, +// nonce: u128, +// amount: u64, +// bedrock_account_pk: [u8; 32], +// signing_key: &lee::PrivateKey, +// ) -> LeeTransaction { +// let message = lee::public_transaction::Message::try_new( +// programs::bridge().id(), +// vec![sender, system_accounts::bridge_account_id()], +// vec![nonce.into()], +// bridge_core::Instruction::Withdraw { +// amount, +// bedrock_account_pk, +// }, +// ) +// .unwrap(); +// let witness_set = lee::public_transaction::WitnessSet::for_message(&message, &[signing_key]); +// LeeTransaction::Public(lee::PublicTransaction::new(message, witness_set)) +// } -/// The reconciliation key a produced block carries for `withdraw_tx`, keyed on -/// the note [`MockBlockPublisher`] reports as released for it. -fn produced_withdraw_key(withdraw_tx: &LeeTransaction) -> WithdrawalReconciliationKey { - let withdraw_arg = crate::extract_bridge_withdraw_data(withdraw_tx).expect("withdraw data"); - let [note_id] = crate::mock::mock_released_notes(std::slice::from_ref(&withdraw_arg))[..] - else { - panic!("A bridge withdraw releases exactly one note"); - }; +// /// The reconciliation key a produced block carries for `withdraw_tx`, keyed on +// /// the note [`MockBlockPublisher`] reports as released for it. +// fn produced_withdraw_key(withdraw_tx: &LeeTransaction) -> WithdrawalReconciliationKey { +// let withdraw_arg = crate::extract_bridge_withdraw_data(withdraw_tx).expect("withdraw data"); +// let [note_id] = crate::mock::mock_released_notes(std::slice::from_ref(&withdraw_arg))[..] +// else { +// panic!("A bridge withdraw releases exactly one note"); +// }; - crate::withdrawal_reconciliation_key(¬e_id) -} +// crate::withdrawal_reconciliation_key(¬e_id) +// } -/// Cold-start backfill re-records an already-finalized deposit event as a -/// pending record before reconstruction replays the same deposit block. -/// Reconstruction must drop that record — its mint is permanently reflected in -/// the reconstructed state (the receipt PDA) — so the next production neither -/// re-mints the vault nor emits a stray deposit tx. -#[tokio::test] -async fn reconstructed_deposit_is_not_reminted_after_backfill_redelivery() { - let recipient = initial_public_user_accounts()[0].account_id; - let deposit_amount = 500_u64; - let withdraw_amount = 100_u64; - let bedrock_account_pk = [0x22_u8; 32]; - let deposit_op_id = [0x0d_u8; 32]; +// /// Cold-start backfill re-records an already-finalized deposit event as a +// /// pending record before reconstruction replays the same deposit block. +// /// Reconstruction must drop that record — its mint is permanently reflected in +// /// the reconstructed state (the receipt PDA) — so the next production neither +// /// re-mints the vault nor emits a stray deposit tx. +// #[tokio::test] +// async fn reconstructed_deposit_is_not_reminted_after_backfill_redelivery() { +// let recipient = initial_public_user_accounts()[0].account_id; +// let deposit_amount = 500_u64; +// let withdraw_amount = 100_u64; +// let bedrock_account_pk = [0x22_u8; 32]; +// let deposit_op_id = [0x0d_u8; 32]; - // Sequencer A produces a deposit block then a withdraw block. - let config_a = bridge_funded_config(); - let (mut seq_a, mempool_a) = - SequencerCoreWithMockClients::start_from_config(config_a.clone()).await; +// // Sequencer A produces a deposit block then a withdraw block. +// let config_a = bridge_funded_config(); +// let (mut seq_a, mempool_a) = +// SequencerCoreWithMockClients::start_from_config(config_a.clone()).await; - let deposit_record = deposit_event_record(deposit_op_id, deposit_amount, recipient); - let deposit_tx = - crate::build_bridge_deposit_tx_from_event(&deposit_record).expect("build deposit tx"); - mempool_a - .push((TransactionOrigin::Sequencer, deposit_tx)) - .await - .unwrap(); - seq_a.produce_new_block().await.unwrap(); +// let deposit_record = deposit_event_record(deposit_op_id, deposit_amount, recipient); +// let deposit_tx = +// crate::build_bridge_deposit_tx_from_event(&deposit_record).expect("build deposit tx"); +// mempool_a +// .push((TransactionOrigin::Sequencer, deposit_tx)) +// .await +// .unwrap(); +// seq_a.produce_new_block().await.unwrap(); - let withdraw_tx = build_public_withdraw_tx( - recipient, - 0, - withdraw_amount, - bedrock_account_pk, - &create_signing_key_for_account1(), - ); - mempool_a - .push((TransactionOrigin::User, withdraw_tx.clone())) - .await - .unwrap(); - seq_a.produce_new_block().await.unwrap(); +// let withdraw_tx = build_public_withdraw_tx( +// recipient, +// 0, +// withdraw_amount, +// bedrock_account_pk, +// &create_signing_key_for_account1(), +// ); +// mempool_a +// .push((TransactionOrigin::User, withdraw_tx.clone())) +// .await +// .unwrap(); +// seq_a.produce_new_block().await.unwrap(); - let tip_a = seq_a.block_store().latest_block_meta().unwrap().unwrap(); - let messages = channel_from_store(seq_a.block_store(), 10); - let tip_slot = messages.last().unwrap().1; - let channel_id = config_a.bedrock_config.channel_id; +// let tip_a = seq_a.block_store().latest_block_meta().unwrap().unwrap(); +// let messages = channel_from_store(seq_a.block_store(), 10); +// let tip_slot = messages.last().unwrap().1; +// let channel_id = config_a.bedrock_config.channel_id; - let config_b = bridge_funded_config(); - let (mut seq_b, _mempool_b) = SequencerCoreWithMockClients::start_from_config(config_b).await; +// let config_b = bridge_funded_config(); +// let (mut seq_b, _mempool_b) = +// SequencerCoreWithMockClients::start_from_config(config_b).await; - // Backfill re-delivery: the deposit event is re-recorded as a pending record - // before reconstruction runs. The mint no longer flows through the mempool - // (that sink was removed); the store drain is the only source. - assert!( - seq_b - .block_store() - .dbio() - .add_pending_deposit_event(deposit_record.clone()) - .unwrap() - ); +// // Backfill re-delivery: the deposit event is re-recorded as a pending record +// // before reconstruction runs. The mint no longer flows through the mempool +// // (that sink was removed); the store drain is the only source. +// assert!( +// seq_b +// .block_store() +// .dbio() +// .add_pending_deposit_event(deposit_record.clone()) +// .unwrap() +// ); - let mock_b = MockBlockPublisher::with_canned_channel(channel_id, Some(tip_slot), messages); - SequencerCore::::verify_and_reconstruct( - &mock_b, - &seq_b.store, - &seq_b.chain, - true, - ) - .await - .expect("reconstruct"); +// let mock_b = MockBlockPublisher::with_canned_channel(channel_id, Some(tip_slot), messages); +// SequencerCore::::verify_and_reconstruct( +// &mock_b, +// &seq_b.store, +// &seq_b.chain, +// true, +// ) +// .await +// .expect("reconstruct"); - let tip_b = seq_b.block_store().latest_block_meta().unwrap().unwrap(); - assert_eq!(tip_b.id, tip_a.id); - assert_eq!(tip_b.hash, tip_a.hash); +// let tip_b = seq_b.block_store().latest_block_meta().unwrap().unwrap(); +// assert_eq!(tip_b.id, tip_a.id); +// assert_eq!(tip_b.hash, tip_a.hash); - // Reconstruction replays the finalized deposit block, minting the receipt - // into state and dropping the re-recorded pending event — so the drain has - // nothing left to re-mint. This is the mechanism that protects against the - // re-delivery, in place of the removed mempool sink. - assert!( - seq_b - .block_store() - .dbio() - .get_pending_deposit_events() - .unwrap() - .is_empty(), - "reconstruction must drop the re-delivered pending deposit record" - ); +// // Reconstruction replays the finalized deposit block, minting the receipt +// // into state and dropping the re-recorded pending event — so the drain has +// // nothing left to re-mint. This is the mechanism that protects against the +// // re-delivery, in place of the removed mempool sink. +// assert!( +// seq_b +// .block_store() +// .dbio() +// .get_pending_deposit_events() +// .unwrap() +// .is_empty(), +// "reconstruction must drop the re-delivered pending deposit record" +// ); - seq_b.produce_new_block().await.unwrap(); +// seq_b.produce_new_block().await.unwrap(); - let vault_id = vault_core::compute_vault_account_id(programs::vault().id(), recipient); - let bridge_id = system_accounts::bridge_account_id(); - let state_b = seq_b.chain().lock().unwrap().head_state().clone(); - let state_a = seq_a.chain().lock().unwrap().head_state().clone(); - for account in [vault_id, bridge_id, recipient] { - assert_eq!( - state_b.get_account_by_id(account).balance, - state_a.get_account_by_id(account).balance, - "reconstructed balance mismatch for {account:?}", - ); - } - assert_eq!( - state_b.get_account_by_id(vault_id).balance, - u128::from(deposit_amount), - "deposit must mint into the recipient vault exactly once, not twice" - ); +// let vault_id = vault_core::compute_vault_account_id(programs::vault().id(), recipient); +// let bridge_id = system_accounts::bridge_account_id(); +// let state_b = seq_b.chain().lock().unwrap().head_state().clone(); +// let state_a = seq_a.chain().lock().unwrap().head_state().clone(); +// for account in [vault_id, bridge_id, recipient] { +// assert_eq!( +// state_b.get_account_by_id(account).balance, +// state_a.get_account_by_id(account).balance, +// "reconstructed balance mismatch for {account:?}", +// ); +// } +// assert_eq!( +// state_b.get_account_by_id(vault_id).balance, +// u128::from(deposit_amount), +// "deposit must mint into the recipient vault exactly once, not twice" +// ); - let produced = seq_b - .block_store() - .get_block_at_id(tip_b.id + 1) - .unwrap() - .expect("produced block present"); - assert!( - !produced - .body - .transactions - .iter() - .any(|tx| crate::extract_bridge_deposit_id(tx) == Some(HashType(deposit_op_id))), - "the re-delivered mint must be skipped, not re-included in a block" - ); +// let produced = seq_b +// .block_store() +// .get_block_at_id(tip_b.id + 1) +// .unwrap() +// .expect("produced block present"); +// assert!( +// !produced +// .body +// .transactions +// .iter() +// .any(|tx| crate::extract_bridge_deposit_id(tx) == Some(HashType(deposit_op_id))), +// "the re-delivered mint must be skipped, not re-included in a block" +// ); - // A reconstructed withdraw's finalized L1 event was already re-delivered (and - // dropped) by cold-start backfill, so it will never be consumed again. - // Reconstruction must not count it, or the count stays phantom-inflated forever. - let key = produced_withdraw_key(&withdraw_tx); - assert!( - !seq_b - .block_store() - .dbio() - .consume_unseen_withdraw_count(key) - .unwrap(), - "reconstruction must not leave a phantom unseen-withdraw count" - ); -} +// // A reconstructed withdraw's finalized L1 event was already re-delivered (and +// // dropped) by cold-start backfill, so it will never be consumed again. +// // Reconstruction must not count it, or the count stays phantom-inflated forever. +// let key = produced_withdraw_key(&withdraw_tx); +// assert!( +// !seq_b +// .block_store() +// .dbio() +// .consume_unseen_withdraw_count(key) +// .unwrap(), +// "reconstruction must not leave a phantom unseen-withdraw count" +// ); +// } -/// A reconstructed withdraw block must not touch the unseen-withdraw counter. -/// Its finalized L1 Withdraw event was already re-delivered (and dropped as a -/// no-op) by cold-start backfill, so counting it during reconstruction would -/// leave a permanent phantom that nothing ever consumes. -#[tokio::test] -async fn reconstructed_withdraw_leaves_no_phantom_unseen_count() { - let recipient = initial_public_user_accounts()[0].account_id; - let withdraw_amount = 100_u64; - let bedrock_account_pk = [0x33_u8; 32]; +// /// A reconstructed withdraw block must not touch the unseen-withdraw counter. +// /// Its finalized L1 Withdraw event was already re-delivered (and dropped as a +// /// no-op) by cold-start backfill, so counting it during reconstruction would +// /// leave a permanent phantom that nothing ever consumes. +// #[tokio::test] +// async fn reconstructed_withdraw_leaves_no_phantom_unseen_count() { +// let recipient = initial_public_user_accounts()[0].account_id; +// let withdraw_amount = 100_u64; +// let bedrock_account_pk = [0x33_u8; 32]; - // Sequencer A produces a single withdraw block; treat its chain as the channel. - let config_a = bridge_funded_config(); - let (mut seq_a, mempool_a) = - SequencerCoreWithMockClients::start_from_config(config_a.clone()).await; - let withdraw_tx = build_public_withdraw_tx( - recipient, - 0, - withdraw_amount, - bedrock_account_pk, - &create_signing_key_for_account1(), - ); - mempool_a - .push((TransactionOrigin::User, withdraw_tx.clone())) - .await - .unwrap(); - seq_a.produce_new_block().await.unwrap(); +// // Sequencer A produces a single withdraw block; treat its chain as the channel. +// let config_a = bridge_funded_config(); +// let (mut seq_a, mempool_a) = +// SequencerCoreWithMockClients::start_from_config(config_a.clone()).await; +// let withdraw_tx = build_public_withdraw_tx( +// recipient, +// 0, +// withdraw_amount, +// bedrock_account_pk, +// &create_signing_key_for_account1(), +// ); +// mempool_a +// .push((TransactionOrigin::User, withdraw_tx.clone())) +// .await +// .unwrap(); +// seq_a.produce_new_block().await.unwrap(); - let key = produced_withdraw_key(&withdraw_tx); - // Producing the withdraw counts it as unseen, awaiting its L1 event. - assert!( - seq_a - .block_store() - .dbio() - .consume_unseen_withdraw_count(key) - .unwrap(), - "producing a withdraw must count it as unseen" - ); +// let key = produced_withdraw_key(&withdraw_tx); +// // Producing the withdraw counts it as unseen, awaiting its L1 event. +// assert!( +// seq_a +// .block_store() +// .dbio() +// .consume_unseen_withdraw_count(key) +// .unwrap(), +// "producing a withdraw must count it as unseen" +// ); - let messages = channel_from_store(seq_a.block_store(), 10); - let tip_slot = messages.last().unwrap().1; - let channel_id = config_a.bedrock_config.channel_id; +// let messages = channel_from_store(seq_a.block_store(), 10); +// let tip_slot = messages.last().unwrap().1; +// let channel_id = config_a.bedrock_config.channel_id; - // Sequencer B reconstructs A's chain from a fresh store. - let config_b = bridge_funded_config(); - let (store_b, chain_b) = fresh_store_and_chain(&config_b); - let mock_b = MockBlockPublisher::with_canned_channel(channel_id, Some(tip_slot), messages); - SequencerCore::::verify_and_reconstruct(&mock_b, &store_b, &chain_b, true) - .await - .expect("reconstruct"); +// // Sequencer B reconstructs A's chain from a fresh store. +// let config_b = bridge_funded_config(); +// let (store_b, chain_b) = fresh_store_and_chain(&config_b); +// let mock_b = MockBlockPublisher::with_canned_channel(channel_id, Some(tip_slot), messages); +// SequencerCore::::verify_and_reconstruct(&mock_b, &store_b, &chain_b, +// true) .await +// .expect("reconstruct"); - assert!( - !store_b.dbio().consume_unseen_withdraw_count(key).unwrap(), - "reconstruction must not leave a phantom unseen-withdraw count" - ); -} +// assert!( +// !store_b.dbio().consume_unseen_withdraw_count(key).unwrap(), +// "reconstruction must not leave a phantom unseen-withdraw count" +// ); +// } /// A deposit whose L1 event was observed (an unfulfilled pending record /// exists) and whose L2 mint is already contained in a finalized channel block.