overflow.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. use std::time::Duration;
  2. use anyhow::{bail, Result};
  3. use cdk::amount::SplitTarget;
  4. use cdk::dhke::construct_proofs;
  5. use cdk::nuts::{PreMintSecrets, SwapRequest};
  6. use cdk::Amount;
  7. use cdk::HttpClient;
  8. use cdk_integration_tests::{create_backends_fake_wallet, mint_proofs, start_mint, MINT_URL};
  9. /// This attempts to swap for more outputs then inputs.
  10. /// This will work if the mint does not check for outputs amounts overflowing
  11. async fn attempt_to_swap_by_overflowing() -> Result<()> {
  12. let wallet_client = HttpClient::new();
  13. let mint_keys = wallet_client.get_mint_keys(MINT_URL.parse()?).await?;
  14. let mint_keys = mint_keys.first().unwrap();
  15. let keyset_id = mint_keys.id;
  16. let pre_swap_proofs = mint_proofs(MINT_URL, 1.into(), keyset_id, mint_keys).await?;
  17. println!(
  18. "Pre swap amount: {:?}",
  19. Amount::try_sum(pre_swap_proofs.iter().map(|p| p.amount))?
  20. );
  21. println!(
  22. "Pre swap amounts: {:?}",
  23. pre_swap_proofs
  24. .iter()
  25. .map(|p| p.amount)
  26. .collect::<Vec<Amount>>()
  27. );
  28. // Construct messages that will overflow
  29. let amount = 2_u64.pow(63);
  30. let pre_mint_amount =
  31. PreMintSecrets::random(keyset_id, amount.into(), &SplitTarget::default())?;
  32. let pre_mint_amount_two =
  33. PreMintSecrets::random(keyset_id, amount.into(), &SplitTarget::default())?;
  34. let mut pre_mint = PreMintSecrets::random(keyset_id, 1.into(), &SplitTarget::default())?;
  35. pre_mint.combine(pre_mint_amount);
  36. pre_mint.combine(pre_mint_amount_two);
  37. let swap_request = SwapRequest::new(pre_swap_proofs.clone(), pre_mint.blinded_messages());
  38. let swap_response = match wallet_client
  39. .post_swap(MINT_URL.parse()?, swap_request)
  40. .await
  41. {
  42. Ok(res) => res,
  43. // In the context of this test an error response here is good.
  44. // It means the mint does not allow us to swap for more then we should by overflowing
  45. Err(_err) => return Ok(()),
  46. };
  47. let post_swap_proofs = construct_proofs(
  48. swap_response.signatures,
  49. pre_mint.rs(),
  50. pre_mint.secrets(),
  51. &mint_keys.clone().keys,
  52. )?;
  53. println!(
  54. "Pre swap amount: {:?}",
  55. Amount::try_sum(pre_swap_proofs.iter().map(|p| p.amount)).expect("Amount overflowed")
  56. );
  57. println!(
  58. "Post swap amount: {:?}",
  59. Amount::try_sum(post_swap_proofs.iter().map(|p| p.amount)).expect("Amount Overflowed")
  60. );
  61. println!(
  62. "Pre swap amounts: {:?}",
  63. pre_swap_proofs
  64. .iter()
  65. .map(|p| p.amount)
  66. .collect::<Vec<Amount>>()
  67. );
  68. println!(
  69. "Post swap amounts: {:?}",
  70. post_swap_proofs
  71. .iter()
  72. .map(|p| p.amount)
  73. .collect::<Vec<Amount>>()
  74. );
  75. bail!("Should not have been able to swap")
  76. }
  77. #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
  78. pub async fn test_overflow() -> Result<()> {
  79. tokio::spawn(async move {
  80. let ln_backends = create_backends_fake_wallet();
  81. start_mint(ln_backends).await.expect("Could not start mint")
  82. });
  83. // Wait for mint server to start
  84. tokio::time::sleep(Duration::from_millis(500)).await;
  85. let result = attempt_to_swap_by_overflowing().await;
  86. assert!(result.is_ok());
  87. Ok(())
  88. }