Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improvement(ARRR): improve shielded transactions change notes handling in swaps #2331

Open
wants to merge 13 commits into
base: dev
Choose a base branch
from

Conversation

borngraced
Copy link
Member

@borngraced borngraced commented Jan 29, 2025

I found out that we can't spend them(change note) right away. This is because in Zcash, every note that you want to spend needs a nullifier - which is basically like a marker that shows if the note has been spent or not.
The problem is that change notes don't get their nullifier until after the original transaction is mined or so. So even though we might want to treat change notes just like regular received notes(the hack in previous PR), we can't, because they're missing this important nullifier until the transaction is confirmed on the blockchain.
I had originally thought we could save change notes as regular received notes, but I was wrong about this because of the missing nullifier issue.

Change notes are unspendable until confirmed

So, I implemented a mechanism that tracks transactions containing change notes and waits for their confirmations before allowing those notes to be used in new transactions.

I also found a bug in WASM walletdb impl which I've fixed in this PR.

cc @shamardy

@cipig
Copy link
Member

cipig commented Jan 29, 2025

tried to swap ARRR with this, but still getting same error

      {
         "event" : {
            "data" : {
               "error" : "taker_swap:1320] mm2src/coins/z_coin.rs:1233] z_coin:500] z_coin:483] GenTxError(SaveChangeNotesError(\"storage:206] NOT NULL constraint failed: received_notes.nf\"))"
            },
            "type" : "TakerFeeSendFailed"
         },
         "timestamp" : 1738160344119
      },

@borngraced borngraced changed the title fix(ARRR): allow storing empty nullifier for unspent/change notes fix(ARRR): require nullifier for only mined txs in WASM walletdb Jan 29, 2025
@borngraced
Copy link
Member Author

tried to swap ARRR with this, but still getting same error

      {
         "event" : {
            "data" : {
               "error" : "taker_swap:1320] mm2src/coins/z_coin.rs:1233] z_coin:500] z_coin:483] GenTxError(SaveChangeNotesError(\"storage:206] NOT NULL constraint failed: received_notes.nf\"))"
            },
            "type" : "TakerFeeSendFailed"
         },
         "timestamp" : 1738160344119
      },

@cipig #2331 (comment)

@borngraced borngraced changed the title fix(ARRR): require nullifier for only mined txs in WASM walletdb enhancement(ARRR): improve shielded transactions change notes handling in swaps Jan 30, 2025
@borngraced
Copy link
Member Author

@cipig can you please retry again? I've made some changes to this PR 🙏🏾

@borngraced borngraced force-pushed the fix-arrr-note-saving branch from f149bb3 to e735df9 Compare January 30, 2025 15:56
@borngraced borngraced changed the title enhancement(ARRR): improve shielded transactions change notes handling in swaps improvement(ARRR): improve shielded transactions change notes handling in swaps Jan 30, 2025
@cipig
Copy link
Member

cipig commented Jan 30, 2025

started a swap with https://sdk.devbuilds.komodo.earth/fix-arrr-note-saving/mm2_e735df9-linux-x86-64.zip
takerfee ARRR now worked fine, takerpayment failed though:

taker_swap:1700] mm2src/coins/z_coin.rs:1348] z_coin:572] client:878] Rpc(ResponseParseError(JsonRpcError { client_info: "coin: ARRR", request: JsonRpcRequest { jsonrpc: "2.0", id: 334, method: "blockchain.transaction.broadcast", params: [String("0400008085202f89000283aa22dd0800000017a91438b6fd31949ceef35e9ab3d8c25ec5755603e3ae8700000000000000006e6a4c6b6304381d9c67b17521020610f02dfb60f513b41b36221eb0b5c87377f0d48f6ed517848c7c2a793a40c0ac6782012088a914d31a8da756208b326a8294f90f8474f73d210da288210258a9e9b3332e186457ab8d91852fadb2f7bd9dd4d53f6813e5172ce8ec4f3c9cac6800000000b12732006bae22dd0800000001476c2687d8429860995e5ffee5b2c33b4e7de524ad686560599e787d4bc2d52c559d26f60c74a6696255d4bb69374e7234eae0d4ca337d34511b71e2f8d3e2178339f7d89effb8e07c088d9f59720370cff344fd1e995d6bcee157df4c4e19d6f4a8addde098cf8510dba764fec23959f7ede601ee64bb292c120fc2ccbe42dda669c33e817b1a5a0e6c467cf9262b92b39dc2efe62838d36553207b1e5f211cea05c662326b260291de0da2477a544a988f434504438e291c7a74f3219a04c52221626f89655745d2a6b1bff59307ff40b859413cc98be7c461f48b6c6e06150609f73420e1b34eda8d94e68df518ceff18c3d5e5998f31862632519ad4ea8594364d51c9c36b1ae841c591f7dbfa85947534056f176fe65c4086774840fbde80fe0643ec6325bd51f34a0c17ee01202398f5d3d214fe58d32eab90f96b80b1b4dc3de9ae93968a0eaea8f99d0da8a9fc9f9562f6442ca309af12914e244e3fc027243724e3be3baa08ecc8e8ad18707d54b4cd2380d590804456bff023830102352ac2546581ce8a0177ecd4de639f8bdd699bc977b664ab131ca6ee7f4c0866d6ec4e97799523eac8ceeeccd7f497abb590fceeb598e5f3166effdba72b874fd12b942827a91cf5c678a884ced816a779930cc009301098f07a972d86497958111d960175eaa25dc367107906fc15638aa503c870173cbe0ff862028ef31a0e976c4e72d55dc83eadf7504425619061e8b2f671acf84b4218a0874e5221f3fec84ce350db5f26621b65522dee3c14fb7f1014da99d38bd31687e6df65f09641d84c656be94d3c250ee1d875e6a972bc8748ae0d695b911e4a865050c12fae8a4802f410b8e65627d94f917a586dd87fb89a022ff16434100d997a6539e38f57d2cbc2c04ec9abfc51640d7257c1aa7b230648a91f116c23a996eb54453ae42f5cf074459f1a0086cb479f65f4b00b0c2c652ea508cb73ac553727dd726503666911da15dbb4abb614b2aa498473bf5cdc4481e045816dea13d79ce8f114262d50c1965f02a48a22bf5c46f6aa1a924e997858e8ede13a250a5b47cfee9d16e8617f5c356bf46fdfd1b7af1efe741f1325d485cf3e0a7c9d83c05f632e206d8fc7b28ad8c51a5602909e93a595b8932e40d593380143a2fce9be448bbd5e242d24748bad18ba2fdf48369c023b3ac0b0091e47d7245e6420beaee67d047e00bcb1f6426e28912cfd2042fe1e60f61a6ffed2c4d7a244c18d9202a9abb40954b15e29920431438b7e3ac298a8a6e701631397be6b1bd821c7b78251758f781b4cd37128e30ab0ac562d10160385eb40ba7efaf873911bcc2e34e2f12e71ee31a0ca3ec5fbe52369c7bc8aeade98ecd08d04d90fd3fd3d96d7633cb01433eae6b81a69965493518d4586d67e644a7aff39a7766eb8d90a353de0b429f4f3b8aa8ed78d9d82991d73ebf671df521afe529d0c350294af155c7dbda040cb5b45aaf2278316b8cec7781b9c449e6daec29460dcc967dd1c81047238fd5032a6dab0fc2fbde772062820386d842c81b1760c2fe566e587011e69be3cd548f3b82500d753b8e943b17ce8db2eda8560adbf2ceaba836f95a0b0adb56c456b098f29fcb90f4d68b4d7c3fb6afe6e34dc2d9cdacb0ec71c76f5efb1fe957505ab697715eeb5f5c85aa6a7ccad06fdee0427c00d21d5eb98c40e89f953e28758255559301af9ed85da232290c0f9a69d112edc5c315fc10a1f015d229be3abb4a82b6893ef35ff56993f243656001b366900ce7077160a21feb91201a4c2371286f4c64079eb6e6661b28a1c6f46cd2698b99265b7e24309510b452084dd4c34d043413a3948bea0e57b8acdcb9d32b85424e0b1eabf04c06a9ba6273107a01a074728211b3ecd80a90abe3d022ae0344e99aeb52c0eb9eb12ee56968c3c4425ed81cc997161ca0574b935c2c567fc37ed3ca9f65962c09104b9ea330f91dac32f69f0246a7b51b877ef9b60556dd19f61420c5d7ab04889bbc8743bfc04737b9a3628bfbbded722ae7ee08a48fda4c962e06a13867ccfd715f7dc7470958bd9cd12a6119420cdaba817d776736cf0429600abc4df8ceb9d7598c6ed1460f6b88a65359d3a37b866aaba9d6d3fdef612af0d104b0c97e24a8c0e0ac133cb120def1665f0504358fe9bc096587d817ec1b2c21365a092d9f2be9948a27096ba54d57a307048b35337f2d557a9ecd40202acafa5e754c5495cb312be2b6a44e34b95dba6cf8022a89f871ec62ff34c37d16aecc29211188f25c5d309266ba71bcb506b71506bbcaa68e14a3e9f3e5f93bbf20a4d9e6c16c26e9cc278844c0a32403b63c24806688cd149b5804a439f08ce1dbfb1c477f5a740b25b3f9e5882f74bda7898dbcfc4b89c4a937e3aca2104883f1383011cb8e839cb05251c481e265cb01dcc8bf08b1f58d528a9b105db958997217a91142893a26f9c3dd3f8f806e4c02bda5f50eb84aa6ad64973d0e299306f6a317414437f6b7fefd36c32b3c27f0f456b9fadd20b7ae035b169b2b1b4d131e80150c95a2b69def1d7198ba6e49b0edd646f1c4991d3b7f5b8cab56fc931a2d2558ba33f91902686fd6a6eda2fb9cab545cb2b61558e14712e29f912a6ba2437148aea17f6669a9eeff94c9b079ab2dc9266b751471d980ba808ebf77eeed09de300684a1b7ad9ffb2f2854d09583b1c10f041208c8725ea0fea98181bca26bce1aae67e08e8309d360ed72693deec0de26aeb08ee5dc53e2bae44081971999f5a07f34a2ffdca6cf75a110d4f56d4f507b04dcaedaf2133ac97bb4a6e31197cc7dce8c9d0ddc16a996258f2249aa03ae52ffa63f27119dd4ac295b267305a38204fbb96bb21d0120fc4b2963c02f8752189c8b67f827ca38dccaa97d49faeafb1fb964e730d6153f50946e9f4762c36a8a3d12feac413b6bdc744a7f7f6e03d5b711694243d45111a4cd0028761f7712e833f92b10431ddd0002ba55c6e953d68954c5bd0bf5e561fc261b0684d661d1d58f0a008a52496f3a30a8e85c562aa625d2adf47e3cb2079d0e374a39630421b9ef55fc28944b9f753c214e03a59f890478a48a6aca115bc5607551f1d88578f4bdbb3f3bad8efa27c0c540f832a252c07edb21c9b7477249969a0ea73acffdaf03e1595a3923de5a963cc5bee0f5c75b7f54bf4ef1c18a833f81e1194cece226633dc1521c627078b770003791a6e5043a2c105dfff2c4a483ad7cabb1a9f3249f9796db9c7a4e1f1d3cdc107eac1165604a6e443d557d187ff68de9008a0e0b832cb99d708ab0728e107")] }, error: Response(electrum1.cipig.net:20008, Object({"code": Number(1), "message": String("the transaction was rejected by network rules.\n\n\n[0400008085202f89000283aa22dd0800000017a91438b6fd31949ceef35e9ab3d8c25ec5755603e3ae8700000000000000006e6a4c6b6304381d9c67b17521020610f02dfb60f513b41b36221eb0b5c87377f0d48f6ed517848c7c2a793a40c0ac6782012088a914d31a8da756208b326a8294f90f8474f73d210da288210258a9e9b3332e186457ab8d91852fadb2f7bd9dd4d53f6813e5172ce8ec4f3c9cac6800000000b12732006bae22dd0800000001476c2687d8429860995e5ffee5b2c33b4e7de524ad686560599e787d4bc2d52c559d26f60c74a6696255d4bb69374e7234eae0d4ca337d34511b71e2f8d3e2178339f7d89effb8e07c088d9f59720370cff344fd1e995d6bcee157df4c4e19d6f4a8addde098cf8510dba764fec23959f7ede601ee64bb292c120fc2ccbe42dda669c33e817b1a5a0e6c467cf9262b92b39dc2efe62838d36553207b1e5f211cea05c662326b260291de0da2477a544a988f434504438e291c7a74f3219a04c52221626f89655745d2a6b1bff59307ff40b859413cc98be7c461f48b6c6e06150609f73420e1b34eda8d94e68df518ceff18c3d5e5998f31862632519ad4ea8594364d51c9c36b1ae841c591f7dbfa85947534056f176fe65c4086774840fbde80fe0643ec6325bd51f34a0c17ee01202398f5d3d214fe58d32eab90f96b80b1b4dc3de9ae93968a0eaea8f99d0da8a9fc9f9562f6442ca309af12914e244e3fc027243724e3be3baa08ecc8e8ad18707d54b4cd2380d590804456bff023830102352ac2546581ce8a0177ecd4de639f8bdd699bc977b664ab131ca6ee7f4c0866d6ec4e97799523eac8ceeeccd7f497abb590fceeb598e5f3166effdba72b874fd12b942827a91cf5c678a884ced816a779930cc009301098f07a972d86497958111d960175eaa25dc367107906fc15638aa503c870173cbe0ff862028ef31a0e976c4e72d55dc83eadf7504425619061e8b2f671acf84b4218a0874e5221f3fec84ce350db5f26621b65522dee3c14fb7f1014da99d38bd31687e6df65f09641d84c656be94d3c250ee1d875e6a972bc8748ae0d695b911e4a865050c12fae8a4802f410b8e65627d94f917a586dd87fb89a022ff16434100d997a6539e38f57d2cbc2c04ec9abfc51640d7257c1aa7b230648a91f116c23a996eb54453ae42f5cf074459f1a0086cb479f65f4b00b0c2c652ea508cb73ac553727dd726503666911da15dbb4abb614b2aa498473bf5cdc4481e045816dea13d79ce8f114262d50c1965f02a48a22bf5c46f6aa1a924e997858e8ede13a250a5b47cfee9d16e8617f5c356bf46fdfd1b7af1efe741f1325d485cf3e0a7c9d83c05f632e206d8fc7b28ad8c51a5602909e93a595b8932e40d593380143a2fce9be448bbd5e242d24748bad18ba2fdf48369c023b3ac0b0091e47d7245e6420beaee67d047e00bcb1f6426e28912cfd2042fe1e60f61a6ffed2c4d7a244c18d9202a9abb40954b15e29920431438b7e3ac298a8a6e701631397be6b1bd821c7b78251758f781b4cd37128e30ab0ac562d10160385eb40ba7efaf873911bcc2e34e2f12e71ee31a0ca3ec5fbe52369c7bc8aeade98ecd08d04d90fd3fd3d96d7633cb01433eae6b81a69965493518d4586d67e644a7aff39a7766eb8d90a353de0b429f4f3b8aa8ed78d9d82991d73ebf671df521afe529d0c350294af155c7dbda040cb5b45aaf2278316b8cec7781b9c449e6daec29460dcc967dd1c81047238fd5032a6dab0fc2fbde772062820386d842c81b1760c2fe566e587011e69be3cd548f3b82500d753b8e943b17ce8db2eda8560adbf2ceaba836f95a0b0adb56c456b098f29fcb90f4d68b4d7c3fb6afe6e34dc2d9cdacb0ec71c76f5efb1fe957505ab697715eeb5f5c85aa6a7ccad06fdee0427c00d21d5eb98c40e89f953e28758255559301af9ed85da232290c0f9a69d112edc5c315fc10a1f015d229be3abb4a82b6893ef35ff56993f243656001b366900ce7077160a21feb91201a4c2371286f4c64079eb6e6661b28a1c6f46cd2698b99265b7e24309510b452084dd4c34d043413a3948bea0e57b8acdcb9d32b85424e0b1eabf04c06a9ba6273107a01a074728211b3ecd80a90abe3d022ae0344e99aeb52c0eb9eb12ee56968c3c4425ed81cc997161ca0574b935c2c567fc37ed3ca9f65962c09104b9ea330f91dac32f69f0246a7b51b877ef9b60556dd19f61420c5d7ab04889bbc8743bfc04737b9a3628bfbbded722ae7ee08a48fda4c962e06a13867ccfd715f7dc7470958bd9cd12a6119420cdaba817d776736cf0429600abc4df8ceb9d7598c6ed1460f6b88a65359d3a37b866aaba9d6d3fdef612af0d104b0c97e24a8c0e0ac133cb120def1665f0504358fe9bc096587d817ec1b2c21365a092d9f2be9948a27096ba54d57a307048b35337f2d557a9ecd40202acafa5e754c5495cb312be2b6a44e34b95dba6cf8022a89f871ec62ff34c37d16aecc29211188f25c5d309266ba71bcb506b71506bbcaa68e14a3e9f3e5f93bbf20a4d9e6c16c26e9cc278844c0a32403b63c24806688cd149b5804a439f08ce1dbfb1c477f5a740b25b3f9e5882f74bda7898dbcfc4b89c4a937e3aca2104883f1383011cb8e839cb05251c481e265cb01dcc8bf08b1f58d528a9b105db958997217a91142893a26f9c3dd3f8f806e4c02bda5f50eb84aa6ad64973d0e299306f6a317414437f6b7fefd36c32b3c27f0f456b9fadd20b7ae035b169b2b1b4d131e80150c95a2b69def1d7198ba6e49b0edd646f1c4991d3b7f5b8cab56fc931a2d2558ba33f91902686fd6a6eda2fb9cab545cb2b61558e14712e29f912a6ba2437148aea17f6669a9eeff94c9b079ab2dc9266b751471d980ba808ebf77eeed09de300684a1b7ad9ffb2f2854d09583b1c10f041208c8725ea0fea98181bca26bce1aae67e08e8309d360ed72693deec0de26aeb08ee5dc53e2bae44081971999f5a07f34a2ffdca6cf75a110d4f56d4f507b04dcaedaf2133ac97bb4a6e31197cc7dce8c9d0ddc16a996258f2249aa03ae52ffa63f27119dd4ac295b267305a38204fbb96bb21d0120fc4b2963c02f8752189c8b67f827ca38dccaa97d49faeafb1fb964e730d6153f50946e9f4762c36a8a3d12feac413b6bdc744a7f7f6e03d5b711694243d45111a4cd0028761f7712e833f92b10431ddd0002ba55c6e953d68954c5bd0bf5e561fc261b0684d661d1d58f0a008a52496f3a30a8e85c562aa625d2adf47e3cb2079d0e374a39630421b9ef55fc28944b9f753c214e03a59f890478a48a6aca115bc5607551f1d88578f4bdbb3f3bad8efa27c0c540f832a252c07edb21c9b7477249969a0ea73acffdaf03e1595a3923de5a963cc5bee0f5c75b7f54bf4ef1c18a833f81e1194cece226633dc1521c627078b770003791a6e5043a2c105dfff2c4a483ad7cabb1a9f3249f9796db9c7a4e1f1d3cdc107eac1165604a6e443d557d187ff68de9008a0e0b832cb99d708ab0728e107]")})) }))

the transaction was rejected by network rules
likely because the change from takerfee was not confirmed when takerpayment was sent
this is known behavior though, it was like that all the time

@cipig
Copy link
Member

cipig commented Jan 30, 2025

@borngraced
Copy link
Member Author

image second swap with https://sdk.devbuilds.komodo.earth/fix-arrr-note-saving/mm2_13d1dd4-linux-x86-64.zip worked fine

thanks, does this fix the original issue?

@cipig
Copy link
Member

cipig commented Jan 30, 2025

thanks, does this fix the original issue?

yes, the last commits fixed the issue #2331 (comment)

@smk762 smk762 requested review from smk762 and cipig February 3, 2025 03:34
@cipig
Copy link
Member

cipig commented Feb 3, 2025

ARRR change from swaps is not added back to balance
only restart fixes ARRR balance
waiting for a fix

@borngraced
Copy link
Member Author

borngraced commented Feb 3, 2025

ARRR change from swaps is not added back to balance only restart fixes ARRR balance waiting for a fix

Let's try the latest build again 9a76c1b

Please provide the log file as well. thanks

Comment on lines 2455 to 2457
pub fn new_with_unspendable(spendable: BigDecimal, unspendable: BigDecimal) -> CoinBalance {
CoinBalance { spendable, unspendable }
}
Copy link
Member

@onur-ozkan onur-ozkan Feb 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just my opinion, not a game-changer blocker:

It doesn't feel right to have these functions as CoinBalance fields are already pubed and it doesn't have too many fields.

The use of

let _ = CoinBalance {
    spendable,
    unspendable
};

seems more clean than

CoinBalance::new_with_unspendable(x, y)

because we can't know what is the implementation detail behind new_with_unspendable.

@shamardy shamardy requested a review from dimxy February 3, 2025 10:37
@cipig
Copy link
Member

cipig commented Feb 3, 2025

Let's try the latest build again 9a76c1b

Please provide the log file as well. thanks

I did a ARRR swap, selling 22 ARRR
image

ARRR balance before the swap was 15762.45617603
ARRR balance after the swap was 15623.96514865 (so there are some ARRR missing)
ARRR balance after restart of app went back to 15740.43067341 (which is correct)

The log:
2025-02-03-13-57-34.kdf.log

Comment on lines 326 to 342
#[cfg(not(target_arch = "wasm32"))]
async fn my_balance_sat(&self) -> Result<u64, MmError<ZcashClientError>> {
async fn my_balance_sat(&self) -> Result<u64, MmError<ZCoinBalanceError>> {
let wallet_db = self.z_fields.light_wallet_db.clone();
async_blocking(move || {
#[cfg(target_arch = "wasm32")]
let balance_sat: u64 = wallet_db.db.get_balance(AccountId::default()).await?.into();

#[cfg(not(target_arch = "wasm32"))]
let balance_sat: u64 = async_blocking(move || {
let db_guard = wallet_db.db.inner();
let db_guard = db_guard.lock().unwrap();
let balance = get_balance(&db_guard, AccountId::default())?.into();
Ok(balance)
get_balance(&db_guard, AccountId::default()).map(|v| v.into())
})
.await
}
.map_to_mm(|err| ZCoinBalanceError::BalanceError(err.to_string()))?;

#[cfg(target_arch = "wasm32")]
async fn my_balance_sat(&self) -> Result<u64, MmError<ZCoinBalanceError>> {
let wallet_db = self.z_fields.light_wallet_db.clone();
Ok(wallet_db.db.get_balance(AccountId::default()).await?.into())
Ok(balance_sat)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks iffy to me. I liked the previous separation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean not really..

    async fn my_balance_sat(&self) -> Result<u64, MmError<ZCoinBalanceError>> {
        let wallet_db = self.z_fields.light_wallet_db.clone();

        #[cfg(target_arch = "wasm32")]
        let balance_sat: u64 = wallet_db.db.get_balance(AccountId::default()).await?.into();

        #[cfg(not(target_arch = "wasm32"))]
        let balance_sat: u64 = async_blocking(move || {
            let db_guard = wallet_db.db.inner();
            let db_guard = db_guard.lock().unwrap();
            get_balance(&db_guard, AccountId::default()).map(|v| v.into())
        })
        .await
        .map_to_mm(|err| ZCoinBalanceError::BalanceError(err.to_string()))?;

        Ok(balance_sat)
    }

@@ -170,6 +171,7 @@ impl From<GenTxError> for WithdrawError {
GenTxError::DecryptedOutputNotFound
| GenTxError::FailedToGetMerklePath
| GenTxError::PrevTxNotConfirmed
| GenTxError::NeededPrevTxConfirmed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds more like a timeout rather than internal error.

if tx.block.is_none() {
if tx.block.is_some() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the behaviour significantly, do we have a test coverage for this?

Copy link
Member Author

@borngraced borngraced Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check is very much unneeded and will probably never hit that block of code because only tx that's been mined or included in a block can have a nullifier.

This will return only txs included in block

let matching_tx = maybe_txs.iter().find(|(id_tx, _tx)| id_tx.to_bigint() == note.spent);

yep, there's a test here,

async fn test_create_to_address_fails_on_locked_notes() {
..


/// Adds a change note to the tracker.
pub fn add_change_note(&self, tx_hex: Vec<u8>, change_note: BigDecimal) {
let mut tracker = self.tracker.lock().unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: Does tx_hex have constant size?

Copy link
Member Author

@borngraced borngraced Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outdated

Comment on lines 395 to 397
if changes.is_empty() {
Ok(spendable_notes)
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The else block is way too large. Can you please do

if changes.is_empty() {
   return Ok(spendable_notes);
}

and release the else block to improve readability?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outdated

Comment on lines 383 to 396
) -> MmResult<Vec<SpendableNote>, GenTxError> {
let spendable_notes = self
.spendable_notes_ordered()
.await
.map_err(|err| GenTxError::SpendableNotesError(err.to_string()))?;
let changes = self.z_fields.change_tracker.change_notes_iter();
let my_z_balance = self
.my_balance()
.compat()
.await
.mm_err(|err| GenTxError::Internal(err.to_string()))?;

if changes.is_empty() {
Ok(spendable_notes)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If changes is empty, the time spent on my_z_balance will be wasted.

Comment on lines 1221 to 1223
if balance < change {
return MmError::err(BalanceError::WalletStorageError(
"change can't be greater than balance".to_owned(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if I am missing something but WalletStorageError doesn't sound like a good fit for this error.

@dimxy
Copy link
Collaborator

dimxy commented Feb 5, 2025

In this PR zhtlc-native-tests now work (as in the current dev branch some fail).
But I had to add flavor = "multi_thread" to the zombie_coin_send_dex_fee test.
(W/o the 'multi_thread' option an error appeared:

thread 'z_coin::z_coin_native_tests::zombie_coin_send_dex_fee' panicked at 'can call blocking only when running on the multi-threaded runtime', /home/ubuntu/.cargo/git/checkouts/librustzcash-068ee532cb234fc6/4e030a0/zcash_client_sqlite/src/for_async/mod.rs:347:9

Could this error be an issue in a non-test environment?)

@borngraced
Copy link
Member Author

borngraced commented Feb 5, 2025

I believe you want to change the function to async and remove the usage of block_on and await instead @dimxy

#[tokio::test]

@dimxy
Copy link
Collaborator

dimxy commented Feb 5, 2025

I believe you want to change the function to async and remove the usage of block_on and await instead @dimxy

#[tokio::test]

Yes I am aware of that (used this option is my PR #2112 months ago), so I ran the test already with [token::test] and 'block_on' replaced on 'await' and was receiving this error.

I ran more tests in the zhtlc-native-tests mod with the ZOMBIE chain. 4 of them failed with different errors (at least in my env).

Copy link
Member

@cipig cipig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ARRR swaps work fine after latest commits and the balance is correct after swap finished, so no more missing ARRR

Copy link
Collaborator

@shamardy shamardy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only one comment for now

Comment on lines 387 to 406
let prev = self.z_fields.previous_tx_with_change.lock().unwrap().take();
if let Some((tx, _)) = prev {
info!("Waiting for {tx:?} to be confirmed before next tx can be generated");
// Wait up to 30 minutes for confirmations with 15 sec check interval
// (probably will be changed)
let wait_until = now_sec() + (30 * 60);
let input = ConfirmPaymentInput {
payment_tx: tx.clone(),
confirmations: self.required_confirmations(),
requires_nota: self.requires_notarization(),
wait_until,
check_every: 15,
};
self.wait_for_confirmations(input)
.compat()
.await
.map_to_mm(GenTxError::NeededPrevTxConfirmed)?;

info!("Previous transaction confirmed");
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that we can't spend other unrelated notes when a transaction is unconfirmed, it doesn't make sense. Are we sure this was the issue that caused this #2331 (comment) c.c. @cipig

Copy link
Member Author

@borngraced borngraced Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, actually deducting the change from the balance should be already enough if the change from taker_fee won't affect taker_payment.

This is specially for taker fee change to be returned since I assume as taker I don't know when my taker fee is confirmed(if I'm correct) so we need a way to return the change.

Any change created after taker fee e.g taker payment will be returned after confirmation.

Copy link
Member Author

@borngraced borngraced Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checking if change is needed should invalidate Does this mean that we can't spend other unrelated notes when a transaction is unconfirmed but still where do we know when taker_fee is confirmed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure this was the issue that caused this #2331 (comment)

Yes, indeed. I was able to reproduce it myself

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants