use crate::error::BlockError;
use crate::signer::AccountRef;
use super::{can_delegate, BlockOperation, OperationContext, OperationType};
#[derive(Debug, Clone)]
pub struct SetRep {
pub to: AccountRef,
}
impl BlockOperation for SetRep {
const TYPE: OperationType = OperationType::SetRep;
fn validate(&self, ctx: &OperationContext<'_>) -> Result<(), BlockError> {
if !can_delegate(ctx.account.to_keypair_type()) {
return Err(BlockError::IdentifierDelegationForbidden);
}
if self.to.to_keypair_type().is_identifier() {
return Err(BlockError::IdentifierDelegationForbidden);
}
if ctx.iter_type::<SetRep>().count() > 1 {
return Err(BlockError::MultipleSetRep);
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use alloc::vec;
use keetanetwork_account::KeyPairType;
use super::*;
use crate::operation::harness::{assert_validation, token, Harness};
use crate::operation::Operation;
use crate::testing::{generate_ed25519_ref, generate_identifier_ref};
#[test]
fn test_set_rep_validation() {
assert_validation! {
"rejects_token_account":
(Harness::new(token(0)), SetRep { to: generate_ed25519_ref(2) }.into())
=> Err(BlockError::IdentifierDelegationForbidden),
"accepts_storage_account":
(
Harness::new(generate_identifier_ref(1, KeyPairType::STORAGE, 0)),
SetRep { to: generate_ed25519_ref(2) }.into(),
) => Ok(()),
"rejects_identifier_representative":
(Harness::new(generate_ed25519_ref(1)), SetRep { to: token(0) }.into())
=> Err(BlockError::IdentifierDelegationForbidden),
"rejects_multiple_per_block": {
let mut harness = Harness::new(generate_ed25519_ref(1));
let operation: Operation = SetRep { to: generate_ed25519_ref(2) }.into();
harness.operations = vec![operation.clone(), SetRep { to: generate_ed25519_ref(3) }.into()];
(harness, operation)
} => Err(BlockError::MultipleSetRep),
}
}
}