From 83052f0632dfe774c249398f780584375ded7699 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 10 Apr 2026 16:50:43 +0100 Subject: [PATCH 1/2] use verify_transaction_inclusion_v2 --- contracts/mock-btc-light-client/src/lib.rs | 16 ++++++++++++ contracts/satoshi-bridge/src/api/bridge.rs | 16 ++++++++++++ .../active_utxo_management.rs | 4 +++ .../src/btc_light_client/deposit.rs | 8 ++++++ .../src/btc_light_client/mod.rs | 26 +++++++++++++++---- .../src/btc_light_client/withdraw.rs | 4 +++ .../satoshi-bridge/tests/setup/context.rs | 6 +++++ 7 files changed, 75 insertions(+), 5 deletions(-) diff --git a/contracts/mock-btc-light-client/src/lib.rs b/contracts/mock-btc-light-client/src/lib.rs index c7984e0..032f8c1 100644 --- a/contracts/mock-btc-light-client/src/lib.rs +++ b/contracts/mock-btc-light-client/src/lib.rs @@ -29,6 +29,17 @@ pub struct ProofArgs { pub confirmations: u64, } +#[near(serializers = [borsh])] +pub struct ProofArgsV2 { + pub tx_id: H256, + pub tx_block_blockhash: H256, + pub tx_index: u64, + pub merkle_proof: Vec, + pub coinbase_tx_id: H256, + pub coinbase_merkle_proof: Vec, + pub confirmations: u64, +} + impl<'de> Deserialize<'de> for H256 { fn deserialize(deserializer: D) -> Result where @@ -82,6 +93,11 @@ impl Contract { true } + #[allow(unused_variables)] + pub fn verify_transaction_inclusion_v2(&self, #[serializer(borsh)] args: ProofArgsV2) -> bool { + true + } + pub fn get_last_block_height(&self) -> u32 { // Return a reasonable mock block height for Zcash testnet 1000 diff --git a/contracts/satoshi-bridge/src/api/bridge.rs b/contracts/satoshi-bridge/src/api/bridge.rs index 1e0dc9f..c7d7d74 100644 --- a/contracts/satoshi-bridge/src/api/bridge.rs +++ b/contracts/satoshi-bridge/src/api/bridge.rs @@ -29,6 +29,8 @@ impl Contract { tx_block_blockhash: String, tx_index: u64, merkle_proof: Vec, + coinbase_tx_id: String, + coinbase_merkle_proof: Vec, ) -> Promise { require!( deposit_msg.safe_deposit.is_none(), @@ -68,6 +70,8 @@ impl Contract { tx_block_blockhash, tx_index, merkle_proof, + coinbase_tx_id, + coinbase_merkle_proof, PendingUTXOInfo { tx_id, utxo_storage_key, @@ -103,6 +107,8 @@ impl Contract { tx_block_blockhash: String, tx_index: u64, merkle_proof: Vec, + coinbase_tx_id: String, + coinbase_merkle_proof: Vec, ) -> Promise { require!( env::attached_deposit() >= self.required_balance_for_safe_deposit(), @@ -145,6 +151,8 @@ impl Contract { tx_block_blockhash, tx_index, merkle_proof, + coinbase_tx_id, + coinbase_merkle_proof, PendingUTXOInfo { tx_id, utxo_storage_key, @@ -175,6 +183,8 @@ impl Contract { tx_block_blockhash: String, tx_index: u64, merkle_proof: Vec, + coinbase_tx_id: String, + coinbase_merkle_proof: Vec, ) -> Promise { let btc_pending_info = self.internal_unwrap_btc_pending_info(&tx_id); btc_pending_info.assert_withdraw_related_pending_verify_tx(); @@ -193,6 +203,8 @@ impl Contract { tx_block_blockhash, tx_index, merkle_proof, + coinbase_tx_id, + coinbase_merkle_proof, btc_pending_info, ) } @@ -276,6 +288,8 @@ impl Contract { tx_block_blockhash: String, tx_index: u64, merkle_proof: Vec, + coinbase_tx_id: String, + coinbase_merkle_proof: Vec, ) -> Promise { let btc_pending_info = self.internal_unwrap_btc_pending_info(&tx_id); btc_pending_info.assert_active_utxo_management_related_pending_verify_tx(); @@ -294,6 +308,8 @@ impl Contract { tx_block_blockhash, tx_index, merkle_proof, + coinbase_tx_id, + coinbase_merkle_proof, btc_pending_info, ) } diff --git a/contracts/satoshi-bridge/src/btc_light_client/active_utxo_management.rs b/contracts/satoshi-bridge/src/btc_light_client/active_utxo_management.rs index 385470e..a5e5b1c 100644 --- a/contracts/satoshi-bridge/src/btc_light_client/active_utxo_management.rs +++ b/contracts/satoshi-bridge/src/btc_light_client/active_utxo_management.rs @@ -12,6 +12,8 @@ impl Contract { tx_block_blockhash: String, tx_index: u64, merkle_proof: Vec, + coinbase_tx_id: String, + coinbase_merkle_proof: Vec, btc_pending_info: &BTCPendingInfo, ) -> Promise { let config = self.internal_config(); @@ -22,6 +24,8 @@ impl Contract { tx_block_blockhash, tx_index, merkle_proof, + coinbase_tx_id, + coinbase_merkle_proof, confirmations, ) .then( diff --git a/contracts/satoshi-bridge/src/btc_light_client/deposit.rs b/contracts/satoshi-bridge/src/btc_light_client/deposit.rs index 6f9a40a..672653d 100644 --- a/contracts/satoshi-bridge/src/btc_light_client/deposit.rs +++ b/contracts/satoshi-bridge/src/btc_light_client/deposit.rs @@ -19,6 +19,8 @@ impl Contract { tx_block_blockhash: String, tx_index: u64, merkle_proof: Vec, + coinbase_tx_id: String, + coinbase_merkle_proof: Vec, pending_utxo_info: PendingUTXOInfo, deposit_msg: DepositMsg, ) -> Promise { @@ -35,6 +37,8 @@ impl Contract { tx_block_blockhash, tx_index, merkle_proof, + coinbase_tx_id, + coinbase_merkle_proof, confirmations, ); @@ -74,6 +78,8 @@ impl Contract { tx_block_blockhash: String, tx_index: u64, merkle_proof: Vec, + coinbase_tx_id: String, + coinbase_merkle_proof: Vec, pending_utxo_info: PendingUTXOInfo, recipient_id: AccountId, deposit_msg: SafeDepositMsg, @@ -86,6 +92,8 @@ impl Contract { tx_block_blockhash, tx_index, merkle_proof, + coinbase_tx_id, + coinbase_merkle_proof, confirmations, ); diff --git a/contracts/satoshi-bridge/src/btc_light_client/mod.rs b/contracts/satoshi-bridge/src/btc_light_client/mod.rs index da52466..63857d9 100644 --- a/contracts/satoshi-bridge/src/btc_light_client/mod.rs +++ b/contracts/satoshi-bridge/src/btc_light_client/mod.rs @@ -32,23 +32,27 @@ impl FromStr for H256 { } #[near(serializers = [borsh])] -pub struct ProofArgs { +pub struct ProofArgsV2 { pub tx_id: H256, pub tx_block_blockhash: H256, pub tx_index: u64, pub merkle_proof: Vec, + pub coinbase_tx_id: H256, + pub coinbase_merkle_proof: Vec, pub confirmations: u64, } -impl ProofArgs { +impl ProofArgsV2 { pub fn new( tx_id: String, tx_block_blockhash: String, tx_index: u64, merkle_proof: Vec, + coinbase_tx_id: String, + coinbase_merkle_proof: Vec, confirmations: u64, ) -> Self { - ProofArgs { + ProofArgsV2 { tx_id: tx_id.parse().expect("Invalid tx_id"), tx_block_blockhash: tx_block_blockhash .parse() @@ -61,6 +65,14 @@ impl ProofArgs { .unwrap_or_else(|_| env::panic_str("Invalid merkle_proof: {v:?}")) }) .collect(), + coinbase_tx_id: coinbase_tx_id.parse().expect("Invalid coinbase_tx_id"), + coinbase_merkle_proof: coinbase_merkle_proof + .into_iter() + .map(|v| { + v.parse() + .unwrap_or_else(|_| env::panic_str("Invalid coinbase_merkle_proof: {v:?}")) + }) + .collect(), confirmations, } } @@ -110,7 +122,7 @@ impl Serialize for H256 { #[ext_contract(ext_btc_light_client)] pub trait BtcLightClient { - fn verify_transaction_inclusion(&self, #[serializer(borsh)] args: ProofArgs) -> bool; + fn verify_transaction_inclusion_v2(&self, #[serializer(borsh)] args: ProofArgsV2) -> bool; fn get_last_block_height(&self) -> u32; } @@ -122,15 +134,19 @@ impl Contract { tx_block_blockhash: String, tx_index: u64, merkle_proof: Vec, + coinbase_tx_id: String, + coinbase_merkle_proof: Vec, confirmations: u64, ) -> Promise { ext_btc_light_client::ext(btc_light_client_account_id) .with_static_gas(GAS_FOR_VERIFY_TRANSACTION_INCLUSION) - .verify_transaction_inclusion(ProofArgs::new( + .verify_transaction_inclusion_v2(ProofArgsV2::new( tx_id.clone(), tx_block_blockhash, tx_index, merkle_proof, + coinbase_tx_id, + coinbase_merkle_proof, confirmations, )) } diff --git a/contracts/satoshi-bridge/src/btc_light_client/withdraw.rs b/contracts/satoshi-bridge/src/btc_light_client/withdraw.rs index 794a068..60c3790 100644 --- a/contracts/satoshi-bridge/src/btc_light_client/withdraw.rs +++ b/contracts/satoshi-bridge/src/btc_light_client/withdraw.rs @@ -13,6 +13,8 @@ impl Contract { tx_block_blockhash: String, tx_index: u64, merkle_proof: Vec, + coinbase_tx_id: String, + coinbase_merkle_proof: Vec, btc_pending_info: &BTCPendingInfo, ) -> Promise { let config = self.internal_config(); @@ -23,6 +25,8 @@ impl Contract { tx_block_blockhash, tx_index, merkle_proof, + coinbase_tx_id, + coinbase_merkle_proof, confirmations, ) .then( diff --git a/contracts/satoshi-bridge/tests/setup/context.rs b/contracts/satoshi-bridge/tests/setup/context.rs index 5885cd3..42c9ec8 100644 --- a/contracts/satoshi-bridge/tests/setup/context.rs +++ b/contracts/satoshi-bridge/tests/setup/context.rs @@ -825,6 +825,8 @@ impl Context { "tx_block_blockhash": tx_block_blockhash, "tx_index": tx_index, "merkle_proof": merkle_proof, + "coinbase_tx_id": "0000000000000000000000000000000000000000000000000000000000000000", + "coinbase_merkle_proof": merkle_proof, })) .max_gas() .transact() @@ -865,6 +867,8 @@ impl Context { "tx_block_blockhash": tx_block_blockhash, "tx_index": tx_index, "merkle_proof": merkle_proof, + "coinbase_tx_id": "0000000000000000000000000000000000000000000000000000000000000000", + "coinbase_merkle_proof": merkle_proof, })) .max_gas() .transact() @@ -886,6 +890,8 @@ impl Context { "tx_block_blockhash": tx_block_blockhash, "tx_index": tx_index, "merkle_proof": merkle_proof, + "coinbase_tx_id": "0000000000000000000000000000000000000000000000000000000000000000", + "coinbase_merkle_proof": merkle_proof, })) .max_gas() .transact() From 60540fadb9c62158a3cae65d157799017df4b1c5 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 10 Apr 2026 18:58:51 +0100 Subject: [PATCH 2/2] bump version --- contracts/mock-btc-light-client/Cargo.toml | 2 +- contracts/satoshi-bridge/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/mock-btc-light-client/Cargo.toml b/contracts/mock-btc-light-client/Cargo.toml index 614d440..7821c66 100644 --- a/contracts/mock-btc-light-client/Cargo.toml +++ b/contracts/mock-btc-light-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mock-btc-light-client" -version = "0.1.0" +version = "0.2.0" edition.workspace = true publish.workspace = true diff --git a/contracts/satoshi-bridge/Cargo.toml b/contracts/satoshi-bridge/Cargo.toml index 3acc25a..f0ea986 100644 --- a/contracts/satoshi-bridge/Cargo.toml +++ b/contracts/satoshi-bridge/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "satoshi-bridge" -version = "0.7.5" +version = "0.8.0" edition.workspace = true publish.workspace = true repository.workspace = true