libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit e45345f475c905f56bb2448765f91d6e701cd608
parent c501cccd28b221eb3a8e98434395f45af29c0b71
Author: Antoine A <>
Date:   Tue, 29 Sep 2026 21:01:36 +0200

common: sync with taler-rust and prepared transfer fixes

Diffstat:
M.gitignore | 1+
MCargo.lock | 129++++++++++++++++++++++++++++++++++++++-----------------------------------------
Mdatabase-versioning/libeufin-bank-procedures.sql | 6+++---
Mdatabase-versioning/libeufin-nexus-procedures.sql | 10+++++-----
Mlibeufin-bank/src/api/prepared.rs | 12++++++------
5 files changed, 77 insertions(+), 81 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -21,3 +21,4 @@ debian/files debian/*.substvars debian/*debhelper* azurite +target diff --git a/Cargo.lock b/Cargo.lock @@ -390,9 +390,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.4.7" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54413ede23c2daf518f35156dfde027feb2374004d63bd497f983c8db9c0e313" +checksum = "f360145194ee8e21db5ee7f3fcd4fe52210864c75c985dae33218202c8bbe040" dependencies = [ "find-msvc-tools", "jobserver", @@ -948,13 +948,12 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" -version = "0.8.41" +version = "0.8.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5ef0006ac9ab233c38522f5ae99cae3625151de8f706cacee1cba4b8e2832a" +checksum = "8e985e0451871ad22fb8d2b6b076e2028a502a0d3950998c2c5c0a4f9b5d9679" dependencies = [ "cfg-if", "core_detect", - "multiversion", "multiversion_no_op", "rustversion", "scopeguard", @@ -1023,9 +1022,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25905e51abafe4dcea6c15fec58c57b601cdbd0ee53d22ea1d3016c587d39b" +checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484" [[package]] name = "flate2" @@ -1367,7 +1366,7 @@ dependencies = [ [[package]] name = "http-client" version = "1.5.0" -source = "git+git://git.taler.net/taler-rust.git/#463d24d76e4a0ed5369e30b3ebd9de269f83b69c" +source = "git+git://git.taler.net/taler-rust.git/#3f6a0fd79c5c9f294536810a2edb2f5419acf326" dependencies = [ "compact_str", "futures-util", @@ -1381,6 +1380,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", + "sse-core", "taler-common", "thiserror", "tokio", @@ -1456,16 +1456,17 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +checksum = "ddc03d96684f9226b8a787cdb71488417b53ab5ea8fdb1dac946cb9431cc8bff" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "bytes", "futures-channel", "futures-util", "http", "http-body", + "httparse", "hyper", "ipnet", "libc", @@ -1757,9 +1758,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.105" +version = "0.3.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e" +checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5" dependencies = [ "cfg-if", "futures-util", @@ -2093,27 +2094,6 @@ dependencies = [ ] [[package]] -name = "multiversion" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ca4bea16ffc3f443cf7d866912118196bfef4c6a1556ca00f9f9b00bb43f7c" -dependencies = [ - "multiversion-macros", -] - -[[package]] -name = "multiversion-macros" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d416831a7317ef4b08bee00b69cbbb9c8763da7959a7026244d6266869f9c83" -dependencies = [ - "proc-macro2", - "quote", - "rustversion", - "syn 3.0.6", -] - -[[package]] name = "multiversion_no_op" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2859,9 +2839,9 @@ dependencies = [ [[package]] name = "rustls-platform-verifier" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +checksum = "1167586491e2b18b8bfbb293e8180ec17c201c4f076d7cb3070ca964e7598f98" dependencies = [ "core-foundation 0.10.1", "core-foundation-sys", @@ -2880,9 +2860,9 @@ dependencies = [ [[package]] name = "rustls-platform-verifier-android" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" +checksum = "eec689c0bc40ff2458a5977b6619cb718087084a18e02a131c599b62d05e1a5f" [[package]] name = "rustls-webpki" @@ -3029,9 +3009,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.23.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "935177bb8c0cd8ca1a4e6d1a2ac8988bea69cab4f9d3a31311e012ad27868ea4" +checksum = "df9adc193c780ef8f159aee8b61e2d5801aaa555e6eb0947fe45530ec506296f" dependencies = [ "serde_core", "serde_with_macros", @@ -3039,9 +3019,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.23.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d607aa01a3cb0ad757d6fd216136910db3c97b102fe686585689615a02dbcdc" +checksum = "3e17bbc68e28663bbbb90df47e058aa7eda4fb445b89fe70457bb94fbccf6e49" dependencies = [ "darling", "proc-macro2", @@ -3163,9 +3143,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.16.1" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba467056f1b547ed52077911161fc86985becbc60e8e1857c8a144dab0def891" +checksum = "f9395f0f0eee849a9b707b2f06bb92a6a422090e2123bb2ef8e87a0e61892a8e" dependencies = [ "serde", ] @@ -3394,6 +3374,20 @@ dependencies = [ ] [[package]] +name = "sse-core" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28f4c044039e70ba5724b7e9dacf9fb610394773d15df2bb629170ca30391c88" +dependencies = [ + "bytes", + "fastrand", + "futures-core", + "memchr", + "pin-project-lite", + "thiserror", +] + +[[package]] name = "stable_deref_trait" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3535,7 +3529,7 @@ dependencies = [ [[package]] name = "taler-api" version = "1.5.0" -source = "git+git://git.taler.net/taler-rust.git/#463d24d76e4a0ed5369e30b3ebd9de269f83b69c" +source = "git+git://git.taler.net/taler-rust.git/#3f6a0fd79c5c9f294536810a2edb2f5419acf326" dependencies = [ "aws-lc-rs", "axum", @@ -3564,12 +3558,12 @@ dependencies = [ [[package]] name = "taler-build" version = "1.5.0" -source = "git+git://git.taler.net/taler-rust.git/#463d24d76e4a0ed5369e30b3ebd9de269f83b69c" +source = "git+git://git.taler.net/taler-rust.git/#3f6a0fd79c5c9f294536810a2edb2f5419acf326" [[package]] name = "taler-common" version = "1.5.0" -source = "git+git://git.taler.net/taler-rust.git/#463d24d76e4a0ed5369e30b3ebd9de269f83b69c" +source = "git+git://git.taler.net/taler-rust.git/#3f6a0fd79c5c9f294536810a2edb2f5419acf326" dependencies = [ "anyhow", "aws-lc-rs", @@ -3599,7 +3593,7 @@ dependencies = [ [[package]] name = "taler-macros" version = "1.5.0" -source = "git+git://git.taler.net/taler-rust.git/#463d24d76e4a0ed5369e30b3ebd9de269f83b69c" +source = "git+git://git.taler.net/taler-rust.git/#3f6a0fd79c5c9f294536810a2edb2f5419acf326" dependencies = [ "proc-macro2", "quote", @@ -3609,7 +3603,7 @@ dependencies = [ [[package]] name = "taler-test-utils" version = "1.5.0" -source = "git+git://git.taler.net/taler-rust.git/#463d24d76e4a0ed5369e30b3ebd9de269f83b69c" +source = "git+git://git.taler.net/taler-rust.git/#3f6a0fd79c5c9f294536810a2edb2f5419acf326" dependencies = [ "aws-lc-rs", "axum", @@ -3779,9 +3773,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.5" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c85f2c3ef0b1cd58b36682f4b17aaa995f0e5db534d85692b4903abce21f67" +checksum = "c9cc2678c2cdd569ef8215e2afd7954ada2ae20b4fdd2c5fe6139a3b02d105db" dependencies = [ "rustls", "tokio", @@ -4181,9 +4175,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.128" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" +checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409" dependencies = [ "cfg-if", "once_cell", @@ -4194,19 +4188,20 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.78" +version = "0.4.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef4c5d3d2cdf5c54f4231181768f5510842e350db025faf1f7163b1030ed928" +checksum = "3cbab34de2d982e9b48e18d216d04c4a6f641066ff19ffb699980f591ee3610e" dependencies = [ "js-sys", + "tokio", "wasm-bindgen", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.128" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" +checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4214,9 +4209,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.128" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" +checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7" dependencies = [ "bumpalo", "proc-macro2", @@ -4227,18 +4222,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.128" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" +checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.105" +version = "0.3.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fbddc4a036f00ec4f18c83445bd3115cb306a91da554919a099d9222fe4a7f8" +checksum = "88261b9deccee56594c11a3460c462c41f58d148598fe70ad77070126a68aba4" dependencies = [ "js-sys", "wasm-bindgen", @@ -4620,18 +4615,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.58" +version = "0.8.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e8fafad82b542ff3717217ecdc736231b59e387768c9630123b4ce4d2db44" +checksum = "6df92bf3d9227be3d53173901ddbffac2babc27ae50f397776ffd6dc33f800cb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.58" +version = "0.8.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595f56e044df4f46a0c9a626f65c3d99eb8488f7e8a8baa12dd76326d9710bf2" +checksum = "ac4f328cf2f05d084e496c3e9c3f33ed0a183656a16e1fcec4d464d8373aec82" dependencies = [ "proc-macro2", "quote", diff --git a/database-versioning/libeufin-bank-procedures.sql b/database-versioning/libeufin-bank-procedures.sql @@ -786,7 +786,7 @@ ELSE UPDATE prepared_transfers SET bank_transaction_id = out_credit_row_id WHERE ( - bank_transaction_id IS NULL AND account_pub = in_metadata AND type='reserve' + bank_transaction_id IS NULL AND account_pub = in_metadata AND in_type=type AND type='reserve' ) OR authorization_pub = local_authorization_pub; IF local_withdrawal_uuid IS NOT NULL THEN PERFORM abort_taler_withdrawal(local_withdrawal_uuid); @@ -836,7 +836,7 @@ BEGIN SELECT (amount != in_amount OR creditor_payto != in_credit_account_payto OR exchange_base_url != in_exchange_base_url - OR metadata != in_metadata + OR metadata IS DISTINCT FROM in_metadata OR wtid != in_wtid) ,transfer_operation_id, transfer_date INTO out_request_uid_reuse, out_tx_row_id, out_timestamp @@ -2317,7 +2317,7 @@ WHERE authorization_pub = in_authorization_pub; -- Check idempotency and delay garbage collection IF FOUND AND idempotent THEN UPDATE prepared_transfers - SET registered_at=in_timestamp + SET registered_at=in_timestamp, authorization_sig=in_authorization_sig WHERE authorization_pub=in_authorization_pub; RETURN; END IF; diff --git a/database-versioning/libeufin-nexus-procedures.sql b/database-versioning/libeufin-nexus-procedures.sql @@ -370,7 +370,7 @@ IF in_type IS NOT NULL AND NOT out_talerable AND out_bounce_id IS NULL THEN UPDATE prepared_transfers SET incoming_transaction_id = out_tx_id WHERE ( - incoming_transaction_id IS NULL AND account_pub = in_metadata AND type='reserve' + incoming_transaction_id IS NULL AND account_pub = in_metadata AND in_type=type AND type='reserve' ) OR authorization_pub = local_authorization_pub; -- We cannot use ON CONFLICT here because conversion use a trigger before insertion that isn't idempotent INSERT INTO talerable_incoming_transactions ( @@ -505,7 +505,7 @@ BEGIN SELECT (amount != in_amount OR credit_payto != in_credit_account_payto OR exchange_base_url != in_exchange_base_url - OR metadata != in_metadata + OR metadata IS DISTINCT FROM in_metadata OR wtid != in_wtid) ,transfer_operations.initiated_outgoing_transaction_id, initiation_time INTO out_request_uid_reuse, out_tx_row_id, out_timestamp @@ -688,15 +688,15 @@ WHERE authorization_pub = in_authorization_pub; -- Check idempotency and delay garbage collection IF idempotent THEN UPDATE prepared_transfers - SET registered_at=in_timestamp + SET registered_at=in_timestamp, authorization_sig=in_authorization_sig WHERE authorization_pub=in_authorization_pub; RETURN; END IF; -- Check reserve pub reuse and reference_number clash out_reserve_pub_reuse=in_type = 'reserve' AND ( - EXISTS(SELECT FROM talerable_incoming_transactions WHERE metadata = in_account_pub AND type = 'reserve') - OR EXISTS(SELECT FROM prepared_transfers WHERE account_pub = in_account_pub AND type = 'reserve' AND authorization_pub != in_authorization_pub) + EXISTS(SELECT FROM talerable_incoming_transactions WHERE metadata=in_account_pub AND type='reserve') + OR EXISTS(SELECT FROM prepared_transfers WHERE account_pub=in_account_pub AND type='reserve' AND authorization_pub != in_authorization_pub) ); out_subject_reuse=EXISTS(SELECT FROM prepared_transfers WHERE authorization_pub != in_authorization_pub AND reference_number = in_reference_number); IF out_reserve_pub_reuse OR out_subject_reuse THEN diff --git a/libeufin-bank/src/api/prepared.rs b/libeufin-bank/src/api/prepared.rs @@ -233,8 +233,8 @@ mod test { ) .await; - ctx.assert_balance("customer", "-504").await; - ctx.assert_balance("exchange", "504").await; + ctx.assert_balance("customer", "-630").await; + ctx.assert_balance("exchange", "630").await; let subject = &format!("Taler MAP:{auth_pub}"); // Non recurrent accept on then bounce @@ -262,8 +262,8 @@ mod test { .assert_error(ErrorCode::BANK_TRANSACTION_NOT_FOUND); ctx.tx_s("customer", "1", "exchange", subject).await; // bounce ctx.tx_s("customer", "1", "exchange", subject).await; // bounce - ctx.assert_balance("customer", "-505").await; - ctx.assert_balance("exchange", "505").await; + ctx.assert_balance("customer", "-631").await; + ctx.assert_balance("exchange", "631").await; // Withdrawal is aborted on completion let res = ctx @@ -287,7 +287,7 @@ mod test { .json(json!({})) .await .assert_error(ErrorCode::BANK_CONFIRM_ABORT_CONFLICT); // Aborted - ctx.assert_balance("customer", "-506").await; - ctx.assert_balance("exchange", "506").await; + ctx.assert_balance("customer", "-632").await; + ctx.assert_balance("exchange", "632").await; } }