use masp_primitives::bls12_381::Scalar;
use masp_primitives::sapling::Nullifier;
use namada_core::address::{self, Address};
use namada_core::hash::Hash;
use namada_core::storage::{self, DbKeySeg, KeySeg};
use namada_systems::trans_token;
const BALANCE_STORAGE_KEY: &str = "balance";
pub const MASP_NULLIFIERS_KEY: &str = "nullifiers";
pub const MASP_NOTE_COMMITMENT_TREE_KEY: &str = "commitment_tree";
pub const MASP_NOTE_COMMITMENT_ANCHOR_PREFIX: &str = "note_commitment_anchor";
pub const MASP_CONVERT_ANCHOR_KEY: &str = "convert_anchor";
pub const MASP_TOKEN_MAP_KEY: &str = "tokens";
pub const MASP_ASSETS_HASH_KEY: &str = "assets_hash";
pub const MASP_LAST_INFLATION_KEY: &str = "last_inflation";
pub const MASP_LAST_LOCKED_AMOUNT_KEY: &str = "last_locked_amount";
pub const MASP_KP_GAIN_KEY: &str = "proportional_gain";
pub const MASP_KD_GAIN_KEY: &str = "derivative_gain";
pub const MASP_LOCKED_AMOUNT_TARGET_KEY: &str = "locked_amount_target";
pub const MASP_MAX_REWARD_RATE_KEY: &str = "max_reward_rate";
pub const MASP_TOTAL_REWARDS: &str = "max_total_rewards";
pub fn masp_kp_gain_key<TransToken: trans_token::Keys>(
token_addr: &Address,
) -> storage::Key {
TransToken::parameter_prefix(token_addr)
.with_segment(MASP_KP_GAIN_KEY.to_owned())
}
pub fn masp_kd_gain_key<TransToken: trans_token::Keys>(
token_addr: &Address,
) -> storage::Key {
TransToken::parameter_prefix(token_addr)
.with_segment(MASP_KD_GAIN_KEY.to_owned())
}
pub fn masp_max_reward_rate_key<TransToken: trans_token::Keys>(
token_addr: &Address,
) -> storage::Key {
TransToken::parameter_prefix(token_addr)
.with_segment(MASP_MAX_REWARD_RATE_KEY.to_owned())
}
pub fn masp_locked_amount_target_key<TransToken: trans_token::Keys>(
token_addr: &Address,
) -> storage::Key {
TransToken::parameter_prefix(token_addr)
.with_segment(MASP_LOCKED_AMOUNT_TARGET_KEY.to_owned())
}
pub fn masp_last_locked_amount_key<TransToken: trans_token::Keys>(
token_address: &Address,
) -> storage::Key {
TransToken::parameter_prefix(token_address)
.with_segment(MASP_LAST_LOCKED_AMOUNT_KEY.to_owned())
}
pub fn masp_last_inflation_key<TransToken: trans_token::Keys>(
token_address: &Address,
) -> storage::Key {
TransToken::parameter_prefix(token_address)
.with_segment(MASP_LAST_INFLATION_KEY.to_owned())
}
pub fn is_masp_balance_key(key: &storage::Key) -> bool {
matches!(
&key.segments[..],
[DbKeySeg::AddressSeg(addr), DbKeySeg::AddressSeg(_token), DbKeySeg::StringSeg(balance), DbKeySeg::AddressSeg(owner)]
if *addr
== Address::Internal(address::InternalAddress::Multitoken)
&& balance == BALANCE_STORAGE_KEY
&& *owner == address::MASP
)
}
pub fn is_masp_key(key: &storage::Key) -> bool {
match &key.segments[..] {
[DbKeySeg::AddressSeg(addr), ..] if *addr == address::MASP => true,
_ => is_masp_balance_key(key),
}
}
pub fn is_masp_transfer_key(key: &storage::Key) -> bool {
match &key.segments[..] {
[DbKeySeg::AddressSeg(addr), DbKeySeg::StringSeg(key)]
if *addr == address::MASP
&& key == MASP_NOTE_COMMITMENT_TREE_KEY =>
{
true
}
[
DbKeySeg::AddressSeg(addr),
DbKeySeg::StringSeg(key),
DbKeySeg::StringSeg(_nullifier),
] if *addr == address::MASP && key == MASP_NULLIFIERS_KEY => true,
_ => is_masp_balance_key(key),
}
}
pub fn is_masp_nullifier_key(key: &storage::Key) -> bool {
matches!(&key.segments[..],
[DbKeySeg::AddressSeg(addr),
DbKeySeg::StringSeg(prefix),
..
] if *addr == address::MASP && prefix == MASP_NULLIFIERS_KEY)
}
pub fn is_masp_commitment_anchor_key(key: &storage::Key) -> bool {
matches!(&key.segments[..],
[DbKeySeg::AddressSeg(addr),
DbKeySeg::StringSeg(prefix),
..
] if *addr == address::MASP && prefix == MASP_NOTE_COMMITMENT_ANCHOR_PREFIX)
}
pub fn is_masp_token_map_key(key: &storage::Key) -> bool {
matches!(&key.segments[..],
[DbKeySeg::AddressSeg(addr),
DbKeySeg::StringSeg(prefix),
] if *addr == address::MASP && prefix == MASP_TOKEN_MAP_KEY)
}
pub fn masp_nullifier_key(nullifier: &Nullifier) -> storage::Key {
storage::Key::from(address::MASP.to_db_key())
.push(&MASP_NULLIFIERS_KEY.to_owned())
.expect("Cannot obtain a storage key")
.push(&Hash(nullifier.0))
.expect("Cannot obtain a storage key")
}
pub fn masp_commitment_tree_key() -> storage::Key {
storage::Key::from(address::MASP.to_db_key())
.push(&MASP_NOTE_COMMITMENT_TREE_KEY.to_owned())
.expect("Cannot obtain a storage key")
}
pub fn masp_commitment_anchor_key(anchor: impl Into<Scalar>) -> storage::Key {
storage::Key::from(address::MASP.to_db_key())
.push(&MASP_NOTE_COMMITMENT_ANCHOR_PREFIX.to_owned())
.expect("Cannot obtain a storage key")
.push(&Hash(anchor.into().to_bytes()))
.expect("Cannot obtain a storage key")
}
pub fn masp_convert_anchor_key() -> storage::Key {
storage::Key::from(address::MASP.to_db_key())
.push(&MASP_CONVERT_ANCHOR_KEY.to_owned())
.expect("Cannot obtain a storage key")
}
pub fn masp_token_map_key() -> storage::Key {
storage::Key::from(address::MASP.to_db_key())
.push(&MASP_TOKEN_MAP_KEY.to_owned())
.expect("Cannot obtain a storage key")
}
pub fn masp_assets_hash_key() -> storage::Key {
storage::Key::from(address::MASP.to_db_key())
.push(&MASP_ASSETS_HASH_KEY.to_owned())
.expect("Cannot obtain a storage key")
}
pub fn masp_total_rewards() -> storage::Key {
storage::Key::from(address::MASP.to_db_key())
.push(&MASP_TOTAL_REWARDS.to_owned())
.expect("Cannot obtain a storage key")
}