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

Murisi/masp test vectors rebased #2427

Merged
merged 7 commits into from
Jan 26, 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 @@
- The test vector generator now supports generating MASP transactions.
([\#2427](https://github.com/anoma/namada/pull/2427))
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ bech32 = "0.8.0"
bimap = {version = "0.6.2", features = ["serde"]}
bit-set = "0.5.2"
blake2b-rs = "0.2.0"
bls12_381 = "0.8"
byte-unit = "4.0.13"
byteorder = "1.4.2"
borsh = {version = "1.2.0", features = ["unstable__schema", "derive"]}
Expand Down Expand Up @@ -105,6 +106,7 @@ ibc-testkit = {version = "0.48.1", default-features = false}
ics23 = "0.11.0"
index-set = { git = "https://github.com/heliaxdev/index-set", tag = "v0.8.1", features = ["serialize-borsh", "serialize-serde"] }
itertools = "0.10.0"
jubjub = "0.10"
k256 = { version = "0.13.0", default-features = false, features = ["ecdsa", "pkcs8", "precomputed-tables", "serde", "std"]}
lazy_static = "1.4.0"
ledger-namada-rs = { git = "https://github.com/Zondax/ledger-namada", tag = "v0.0.12" }
Expand Down
15 changes: 9 additions & 6 deletions crates/apps/src/lib/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use namada::types::masp::{BalanceOwner, ExtendedViewingKey, PaymentAddress};
use namada::types::storage::{
BlockHeight, BlockResults, Epoch, IndexedTx, Key, KeySeg,
};
use namada::types::token::{Change, MaspDenom};
use namada::types::token::{Change, MaspDigitPos};
use namada::{state as storage, token};
use namada_sdk::error::{
is_pinned_error, Error, PinnedBalanceError, QueryError,
Expand Down Expand Up @@ -2409,7 +2409,7 @@ pub async fn query_conversions(
.expect("Conversions should be defined");
// Track whether any non-sentinel conversions are found
let mut conversions_found = false;
for (addr, epoch, amt) in conversions.values() {
for (addr, _denom, digit, epoch, amt) in conversions.values() {
// If the user has specified any targets, then meet them
// If we have a sentinel conversion, then skip printing
if matches!(&target_token, Some(target) if target != addr)
Expand All @@ -2422,23 +2422,25 @@ pub async fn query_conversions(
// Print the asset to which the conversion applies
display!(
context.io(),
"{}[{}]: ",
"{}*2^{}[{}]: ",
tokens.get(addr).cloned().unwrap_or_else(|| addr.clone()),
*digit as u8 * 64,
epoch,
);
// Now print out the components of the allowed conversion
let mut prefix = "";
for (asset_type, val) in amt.components() {
// Look up the address and epoch of asset to facilitate pretty
// printing
let (addr, epoch, _) = &conversions[asset_type];
let (addr, _denom, digit, epoch, _) = &conversions[asset_type];
// Now print out this component of the conversion
display!(
context.io(),
"{}{} {}[{}]",
"{}{} {}*2^{}[{}]",
prefix,
val,
tokens.get(addr).cloned().unwrap_or_else(|| addr.clone()),
*digit as u8 * 64,
epoch
);
// Future iterations need to be prefixed with +
Expand All @@ -2461,7 +2463,8 @@ pub async fn query_conversion<C: namada::ledger::queries::Client + Sync>(
asset_type: AssetType,
) -> Option<(
Address,
MaspDenom,
token::Denomination,
MaspDigitPos,
Epoch,
masp_primitives::transaction::components::I128Sum,
MerklePath<Node>,
Expand Down
17 changes: 8 additions & 9 deletions crates/core/src/types/key/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,15 +499,14 @@ pub mod testing {
arb_keypair::<S>().prop_map(|x| x.ref_to())
}

/// Generate an arbitrary common key
pub fn arb_common_pk() -> impl Strategy<Value = common::PublicKey> {
let ed25519 = arb_pk::<ed25519::SigScheme>()
.prop_map(common::PublicKey::Ed25519)
.sboxed();
let secp256k1 = arb_pk::<secp256k1::SigScheme>()
.prop_map(common::PublicKey::Secp256k1)
.sboxed();
ed25519.prop_union(secp256k1)
prop_compose! {
/// Generate an arbitrary common key
pub fn arb_common_pk()(pk in prop_oneof![
arb_pk::<ed25519::SigScheme>().prop_map(common::PublicKey::Ed25519),
arb_pk::<secp256k1::SigScheme>().prop_map(common::PublicKey::Secp256k1),
]) -> common::PublicKey {
pk
}
}

/// A keypair for tests
Expand Down
79 changes: 67 additions & 12 deletions crates/core/src/types/masp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::str::FromStr;
use borsh::{BorshDeserialize, BorshSerialize};
use borsh_ext::BorshSerializeExt;
use masp_primitives::asset_type::AssetType;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};

use crate::impl_display_and_from_str_via_format;
Expand All @@ -15,23 +16,77 @@ use crate::types::string_encoding::{
self, MASP_EXT_FULL_VIEWING_KEY_HRP, MASP_EXT_SPENDING_KEY_HRP,
MASP_PAYMENT_ADDRESS_HRP,
};
use crate::types::token::MaspDenom;
use crate::types::token::{Denomination, MaspDigitPos};

/// The plain representation of a MASP aaset
#[derive(
BorshSerialize,
BorshDeserialize,
Clone,
Debug,
PartialOrd,
Ord,
PartialEq,
Eq,
Hash,
Serialize,
Deserialize,
)]
pub struct AssetData {
/// The token associated with this asset type
pub token: Address,
/// The denomination associated with the above toke
pub denom: Denomination,
/// The digit position covered by this asset type
pub position: MaspDigitPos,
/// The epoch of the asset type, if any
pub epoch: Option<Epoch>,
}

impl AssetData {
/// Make asset type corresponding to given address and epoch
pub fn encode(&self) -> Result<AssetType, std::io::Error> {
// Timestamp the chosen token with the current epoch
let token_bytes = self.serialize_to_vec();
// Generate the unique asset identifier from the unique token address
AssetType::new(token_bytes.as_ref()).map_err(|_| {
std::io::Error::new(
std::io::ErrorKind::Other,
"unable to create asset type".to_string(),
)
})
}

/// Give this pre-asset type the given epoch if already has an epoch. Return
/// the replaced value.
pub fn redate(&mut self, to: Epoch) -> Option<Epoch> {
if self.epoch.is_some() {
self.epoch.replace(to)
} else {
None
}
}

/// Remove the epoch associated with this pre-asset type
pub fn undate(&mut self) {
self.epoch = None;
}
}

/// Make asset type corresponding to given address and epoch
pub fn encode_asset_type(
token: Address,
denom: Denomination,
position: MaspDigitPos,
epoch: Option<Epoch>,
token: &Address,
denom: MaspDenom,
) -> Result<AssetType, std::io::Error> {
// Timestamp the chosen token with the current epoch
let token_bytes = (token, denom, epoch).serialize_to_vec();
// Generate the unique asset identifier from the unique token address
AssetType::new(token_bytes.as_ref()).map_err(|_| {
std::io::Error::new(
std::io::ErrorKind::Other,
"unable to create asset type".to_string(),
)
})
AssetData {
token,
denom,
position,
epoch,
}
.encode()
}

// enough capacity to store the payment address
Expand Down
25 changes: 15 additions & 10 deletions crates/core/src/types/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ pub struct ConversionState {
#[allow(clippy::type_complexity)]
pub assets: BTreeMap<
AssetType,
((Address, MaspDenom), Epoch, AllowedConversion, usize),
(
(Address, Denomination, MaspDigitPos),
Epoch,
AllowedConversion,
usize,
),
>,
}

Expand Down Expand Up @@ -225,19 +230,19 @@ impl Amount {
}
}

/// Given a u64 and [`MaspDenom`], construct the corresponding
/// Given a u64 and [`MaspDigitPos`], construct the corresponding
/// amount.
pub fn from_masp_denominated(val: u64, denom: MaspDenom) -> Self {
pub fn from_masp_denominated(val: u64, denom: MaspDigitPos) -> Self {
let mut raw = [0u64; 4];
raw[denom as usize] = val;
Self { raw: Uint(raw) }
}

/// Given a u128 and [`MaspDenom`], construct the corresponding
/// Given a u128 and [`MaspDigitPos`], construct the corresponding
/// amount.
pub fn from_masp_denominated_u128(
val: u128,
denom: MaspDenom,
denom: MaspDigitPos,
) -> Option<Self> {
let lo = val as u64;
let hi = (val >> 64) as u64;
Expand Down Expand Up @@ -927,14 +932,14 @@ impl From<Amount> for Uint {
#[repr(u8)]
#[allow(missing_docs)]
#[borsh(use_discriminant = true)]
pub enum MaspDenom {
pub enum MaspDigitPos {
Zero = 0,
One,
Two,
Three,
}

impl From<u8> for MaspDenom {
impl From<u8> for MaspDigitPos {
fn from(denom: u8) -> Self {
match denom {
0 => Self::Zero,
Expand All @@ -946,9 +951,9 @@ impl From<u8> for MaspDenom {
}
}

impl MaspDenom {
impl MaspDigitPos {
/// Iterator over the possible denominations
pub fn iter() -> impl Iterator<Item = MaspDenom> {
pub fn iter() -> impl Iterator<Item = MaspDigitPos> {
// 0, 1, 2, 3
(0u8..4).map(Self::from)
}
Expand Down Expand Up @@ -1275,7 +1280,7 @@ mod tests {
fn test_from_masp_denominated() {
let uint = Uint([15u64, 16, 17, 18]);
let original = Amount::from_uint(uint, 0).expect("Test failed");
for denom in MaspDenom::iter() {
for denom in MaspDigitPos::iter() {
let word = denom.denominate(&original);
assert_eq!(word, denom as u64 + 15u64);
let amount = Amount::from_masp_denominated(word, denom);
Expand Down
4 changes: 2 additions & 2 deletions crates/core/src/types/uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use uint::construct_uint;

use super::dec::{Dec, POS_DECIMAL_PRECISION};
use crate::types::token;
use crate::types::token::{Amount, AmountParseError, MaspDenom};
use crate::types::token::{Amount, AmountParseError, MaspDigitPos};

/// The value zero.
pub const ZERO: Uint = Uint::from_u64(0);
Expand Down Expand Up @@ -569,7 +569,7 @@ impl I256 {
/// using the given denomination.
pub fn from_masp_denominated(
value: impl Into<i128>,
denom: MaspDenom,
denom: MaspDigitPos,
) -> Result<Self, AmountParseError> {
let value = value.into();
let is_negative = value < 0;
Expand Down
44 changes: 22 additions & 22 deletions crates/governance/src/storage/proposal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,13 +574,17 @@ pub mod testing {

/// Generate an arbitrary add or removal of what's generated by the supplied
/// strategy
pub fn arb_add_remove<X: Strategy>(
pub fn arb_add_remove<
Y: Clone + std::fmt::Debug,
X: Strategy<Value = Y>,
>(
strategy: X,
) -> impl Strategy<Value = AddRemove<<X as Strategy>::Value>> {
(0..2, strategy).prop_map(|(discriminant, val)| match discriminant {
0 => AddRemove::Add(val),
1 => AddRemove::Remove(val),
_ => unreachable!(),
strategy.prop_flat_map(|val| {
prop_oneof![
Just(AddRemove::Add(val.clone())),
Just(AddRemove::Remove(val)),
]
})
}

Expand All @@ -599,28 +603,24 @@ pub mod testing {

/// Generate an arbitrary PGF action
pub fn arb_pgf_action() -> impl Strategy<Value = PGFAction> {
arb_add_remove(arb_pgf_target())
.prop_map(PGFAction::Continuous)
.boxed()
.prop_union(arb_pgf_target().prop_map(PGFAction::Retro).boxed())
prop_oneof![
arb_add_remove(arb_pgf_target()).prop_map(PGFAction::Continuous),
arb_pgf_target().prop_map(PGFAction::Retro),
]
}

/// Generate an arbitrary proposal type
pub fn arb_proposal_type() -> impl Strategy<Value = ProposalType> {
option::of(arb_hash())
.prop_map(ProposalType::Default)
.boxed()
.prop_union(
collection::hash_set(
arb_add_remove(arb_non_internal_address()),
0..10,
)
.prop_map(ProposalType::PGFSteward)
.boxed(),
prop_oneof![
option::of(arb_hash()).prop_map(ProposalType::Default),
collection::hash_set(
arb_add_remove(arb_non_internal_address()),
0..10,
)
.or(collection::vec(arb_pgf_action(), 0..10)
.prop_map(ProposalType::PGFPayment)
.boxed())
.prop_map(ProposalType::PGFSteward),
collection::vec(arb_pgf_action(), 0..10)
.prop_map(ProposalType::PGFPayment),
]
}

prop_compose! {
Expand Down
9 changes: 5 additions & 4 deletions crates/governance/src/storage/vote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,10 @@ pub mod testing {

/// Generate an arbitrary proposal vote
pub fn arb_proposal_vote() -> impl Strategy<Value = ProposalVote> {
Just(ProposalVote::Yay)
.boxed()
.prop_union(Just(ProposalVote::Nay).boxed())
.or(Just(ProposalVote::Abstain).boxed())
prop_oneof![
Just(ProposalVote::Yay),
Just(ProposalVote::Nay),
Just(ProposalVote::Abstain),
]
}
}
Loading
Loading