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

Test MASP inverse conversions #4193

Merged
merged 3 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Added tests for MASP inverse conversions.
([\#4193](https://github.com/anoma/namada/pull/4193))
127 changes: 126 additions & 1 deletion crates/shielded_token/src/masp/shielded_wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1989,6 +1989,131 @@ mod test_shielded_wallet {
assert!(wallet.compute_shielded_balance(&vk).await.is_err())
}

// Test that `compute_exchanged_amount` can perform inverse conversions to
// match the desired epoch
#[tokio::test]
async fn test_inverse_conversions() {
let (channel, mut context) = MockNamadaIo::new();
// the response to the current masp epoch query
channel
.send(MaspEpoch::new(5).serialize_to_vec())
.expect("Test failed");
let temp_dir = tempdir().unwrap();
let mut wallet = TestingContext::new(FsShieldedUtils::new(
temp_dir.path().to_path_buf(),
));
let native_token =
TestingContext::<FsShieldedUtils>::query_native_token(
context.client(),
)
.await
.expect("Test failed");
let native_token_denom =
TestingContext::<FsShieldedUtils>::query_denom(
context.client(),
&native_token,
)
.await
.expect("Test failed");

for epoch in 0..=5 {
wallet.add_asset_type(AssetData {
token: native_token.clone(),
denom: native_token_denom,
position: MaspDigitPos::Zero,
epoch: Some(MaspEpoch::new(epoch)),
});
}

for epoch in 0..5 {
let mut conv = I128Sum::from_pair(
AssetData {
token: native_token.clone(),
denom: native_token_denom,
position: MaspDigitPos::Zero,
epoch: Some(MaspEpoch::new(epoch)),
}
.encode()
.unwrap(),
-1,
);
conv += I128Sum::from_pair(
AssetData {
token: native_token.clone(),
denom: native_token_denom,
position: MaspDigitPos::Zero,
epoch: Some(MaspEpoch::new(epoch + 1)),
}
.encode()
.unwrap(),
2,
);
context.add_conversions(
AssetData {
token: native_token.clone(),
denom: native_token_denom,
position: MaspDigitPos::Zero,
epoch: Some(MaspEpoch::new(epoch)),
},
(
native_token.clone(),
native_token_denom,
MaspDigitPos::Zero,
MaspEpoch::new(epoch),
conv,
MerklePath::from_path(vec![], 0),
),
);
}

let vk = arbitrary_vk();
let pa = arbitrary_pa();
// Shield at epoch 5
let asset_data = AssetData {
token: native_token.clone(),
denom: native_token_denom,
position: MaspDigitPos::Zero,
epoch: Some(MaspEpoch::new(5)),
};
wallet.add_asset_type(asset_data.clone());
wallet.add_note(create_note(asset_data.clone(), 10, pa), vk);
let balance = wallet
.compute_shielded_balance(&vk)
.await
.unwrap()
.unwrap_or_else(ValueSum::zero);
// TODO: would be nice to check even earlier epochs but for that we need
// to construct conversions properly, just like the protocol does, i.e.
// with conversions for non-consecutive epochs

// Query the balance with conversions at epoch 4
let amount = wallet
.compute_exchanged_amount(
context.client(),
context.io(),
balance,
MaspEpoch::new(4),
Conversions::new(),
)
.await
.unwrap()
.0;
assert_eq!(
amount,
I128Sum::from_pair(
AssetData {
token: native_token.clone(),
denom: native_token_denom,
position: MaspDigitPos::Zero,
epoch: Some(MaspEpoch::new(4)),
}
.encode()
.unwrap(),
5
)
);
}

#[tokio::test]
// Test that the estimated rewards are 0 when no conversions are available
async fn test_estimate_rewards_no_conversions() {
Expand Down Expand Up @@ -2103,7 +2228,7 @@ mod test_shielded_wallet {
let pa = arbitrary_pa();
let asset_data = AssetData {
token: native_token.clone(),
denom: 0.into(),
denom: native_token_denom,
position: MaspDigitPos::Zero,
epoch: Some(MaspEpoch::new(2)),
};
Expand Down
22 changes: 22 additions & 0 deletions crates/tests/src/integration/masp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1688,6 +1688,28 @@ fn masp_incentives() -> Result<()> {
assert!(captured.result.is_ok());
assert!(captured.contains("nam: 0.18887"));

// Assert the rewards estimate are 0 since we haven't shielded any more
// tokens
let captured = CapturedOutput::of(|| {
run(
&node,
Bin::Client,
vec![
"estimate-shielding-rewards",
"--key",
AA_VIEWING_KEY,
"--node",
validator_one_rpc,
],
)
});
assert!(captured.result.is_ok());
assert!(
captured.contains(
"Estimated native token rewards for the next MASP epoch: 0"
)
);

// Assert NAM balance at MASP pool is exclusively the
// rewards from the shielded BTC
let captured = CapturedOutput::of(|| {
Expand Down
Loading