use crate::tokens::policy_hash::{PolicyHash, POLICY_HASH_SIZE};
#[cfg(any(test, feature = "property-test-api"))]
use proptest::prelude::*;
use chain_core::{
packer::Codec,
property::{Deserialize, ReadError, Serialize, WriteError},
};
use cryptoxide::{blake2b::Blake2b, digest::Digest};
use thiserror::Error;
use typed_bytes::ByteBuilder;
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
any(test, feature = "property-test-api"),
derive(test_strategy::Arbitrary)
)]
pub struct MintingPolicy(
#[cfg_attr(
any(test, feature = "property-test-api"),
strategy(Just(vec![]))
)]
Vec<MintingPolicyEntry>,
);
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MintingPolicyEntry {}
#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum MintingPolicyViolation {
#[error("the policy of this token does not allow minting")]
AdditionalMintingNotAllowed,
}
impl MintingPolicy {
pub fn new() -> Self {
Self(Vec::new())
}
pub fn check_minting_tx(&self) -> Result<(), MintingPolicyViolation> {
if self.0.is_empty() {
return Err(MintingPolicyViolation::AdditionalMintingNotAllowed);
}
for _entry in &self.0 {
unreachable!("implement this when we have actual minting policies");
}
Ok(())
}
pub fn entries(&self) -> &[MintingPolicyEntry] {
&self.0
}
pub fn bytes(&self) -> Vec<u8> {
let bb: ByteBuilder<Self> = ByteBuilder::new();
bb.u8(0).finalize_as_vec()
}
pub fn hash(&self) -> PolicyHash {
let mut result = [0u8; POLICY_HASH_SIZE];
if !self.0.is_empty() {
let mut hasher = Blake2b::new(POLICY_HASH_SIZE);
hasher.input(&self.bytes());
hasher.result(&mut result);
}
result.into()
}
}
impl Default for MintingPolicy {
fn default() -> Self {
Self::new()
}
}
impl Serialize for MintingPolicy {
fn serialized_size(&self) -> usize {
Codec::u8_size()
}
fn serialize<W: std::io::Write>(&self, codec: &mut Codec<W>) -> Result<(), WriteError> {
codec.put_u8(0_u8)
}
}
impl Deserialize for MintingPolicy {
fn deserialize<R: std::io::Read>(codec: &mut Codec<R>) -> Result<Self, ReadError> {
let no_entries = codec.get_u8()?;
if no_entries != 0 {
return Err(ReadError::InvalidData(
"non-zero number of minting policy entries, but they are currently unimplemented"
.to_string(),
));
}
Ok(Self::new())
}
}
#[cfg(any(test, feature = "property-test-api"))]
mod tests {
use super::*;
#[cfg(test)]
use crate::testing::serialization::serialization_bijection;
#[cfg(test)]
use quickcheck::TestResult;
use quickcheck::{Arbitrary, Gen};
impl Arbitrary for MintingPolicy {
fn arbitrary<G: Gen>(_g: &mut G) -> Self {
Self::new()
}
}
quickcheck! {
fn minting_policy_serialization_bijection(policy: MintingPolicy) -> TestResult {
serialization_bijection(policy)
}
}
}