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

implement add and remove method for blacklisting accounts #408

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 30 additions & 10 deletions rust/btp-common/src/error.rs
Expand Up @@ -145,10 +145,18 @@ pub mod errors {
write!(f, "{}{}: {}", label, "InvalidEvenProof", message)
}
BmvError::InvalidSequence { expected, actual } => {
write!(f, "{}{} expected: {}, but got: {}", label, "InvalidSequence", expected, actual)
write!(
f,
"{}{} expected: {}, but got: {}",
label, "InvalidSequence", expected, actual
)
}
BmvError::InvalidSequenceHigher { expected, actual } => {
write!(f, "{}{} expected: {}, but got: {}", label, "InvalidSequenceHigher", expected, actual)
write!(
f,
"{}{} expected: {}, but got: {}",
label, "InvalidSequenceHigher", expected, actual
)
}
}
}
Expand Down Expand Up @@ -181,6 +189,9 @@ pub mod errors {
AccountNotExist,
TokenNotRegistered,
LessThanZero,
UserAlreadyBlacklisted,
UserNotBlacklisted,
BlacklistedUsers { message: String },
}

impl Exception for BshError {
Expand Down Expand Up @@ -271,13 +282,22 @@ pub mod errors {
}
BshError::Unknown => {
write!(f, "{}", "Unknown")
},
}
BshError::LessThanZero => {
write!(f, "{}", "LessThanZero")
},
}
BshError::Failure => {
write!(f, "{}", "Failure")
}
BshError::UserAlreadyBlacklisted => {
write!(f, "{}", "AlreadyBlacklisted")
}
BshError::UserNotBlacklisted => {
write!(f, "{}", "NotBlacklisted")
}
BshError::BlacklistedUsers { message } => {
write!(f, "{}{} for {}", label, "UsersBlacklisted", message)
}
}
}
}
Expand Down Expand Up @@ -308,13 +328,13 @@ pub mod errors {
RouteNotExist,
ServiceExist,
ServiceNotExist,
Unknown{message: String},
Unknown { message: String },
Unreachable { destination: String },
VerifierExist,
VerifierNotExist,
Unauthorized { message: &'static str },
InvalidSequence,
InternalEventHandleNotExists
InternalEventHandleNotExists,
}

impl Exception for BmcError {
Expand All @@ -329,7 +349,7 @@ pub mod errors {
impl From<&BmcError> for u32 {
fn from(bmc_error: &BmcError) -> Self {
match bmc_error {
BmcError::Unknown{message:_} => 0,
BmcError::Unknown { message: _ } => 0,
BmcError::PermissionNotExist => 1,
BmcError::InvalidSerialNo => 2,
BmcError::VerifierExist => 3,
Expand Down Expand Up @@ -400,15 +420,15 @@ pub mod errors {
BmcError::Unreachable { destination } => {
write!(f, "{}{} at {}", label, "Unreachable", destination)
}
BmcError::Unknown {message} => {
write!(f, "{}{}:{}", label, "Unknown",message)
BmcError::Unknown { message } => {
write!(f, "{}{}:{}", label, "Unknown", message)
}
BmcError::InvalidSerialNo => {
write!(f, "{}{}", label, "Invalid Serial No")
}
BmcError::Unauthorized { message } => {
write!(f, "{}{}: {}", label, "Unauthorized", message)
},
}
BmcError::InternalEventHandleNotExists => {
write!(f, "{}{}", label, "NotExistInternalEventHandle")
}
Expand Down
6 changes: 5 additions & 1 deletion rust/near/bsh/bts/Cargo.toml
Expand Up @@ -46,4 +46,8 @@ path = "tests/test_coin_management.rs"

[[test]]
name = "test_coin_transfer"
path = "tests/test_coin_transfer.rs"
path = "tests/test_coin_transfer.rs"

[[test]]
name = "test_blacklist_management"
path = "tests/test_blacklist_management.rs"
7 changes: 7 additions & 0 deletions rust/near/bsh/bts/src/assertion.rs
Expand Up @@ -178,4 +178,11 @@ impl BtpTokenService {
format!("{}", BshError::TokenNotRegistered)
)
}

pub fn ensure_user_blacklisted(&self, user: &AccountId) -> Result<(), BshError> {
if !self.blacklisted_accounts.contains(user) {
return Err(BshError::UserNotBlacklisted);
}
Ok(())
}
}
31 changes: 31 additions & 0 deletions rust/near/bsh/bts/src/blacklist_management.rs
@@ -0,0 +1,31 @@
use super::*;

impl BtpTokenService {
pub fn add_to_blacklist(&mut self, users: Vec<AccountId>) {
users
.iter()
.for_each(|user| self.blacklisted_accounts.add(user));
}

pub fn remove_from_blacklist(&mut self, users: Vec<AccountId>) -> Result<(), BshError> {
let mut non_blacklisted_user: Vec<String> = Vec::new();
users
.iter()
.for_each(|user| match self.ensure_user_blacklisted(user) {
Ok(()) => {
self.blacklisted_accounts.remove(user);
}
Err(_) => non_blacklisted_user.push(user.to_string()),
});
if !non_blacklisted_user.is_empty() {
return Err(BshError::BlacklistedUsers {
message: non_blacklisted_user.join(", "),
});
}
Ok(())
}

pub fn get_blacklisted_user(&self) -> Vec<AccountId> {
self.blacklisted_accounts.to_vec()
}
}
11 changes: 8 additions & 3 deletions rust/near/bsh/bts/src/lib.rs
Expand Up @@ -7,8 +7,9 @@ use libraries::types::{
use libraries::{
types::messages::BtpMessage, types::messages::SerializedMessage,
types::messages::TokenServiceMessage, types::messages::TokenServiceType, types::Asset,
types::AssetFees, types::AssetMetadata, types::Assets, types::Balances, types::Math,
types::Network, types::Owners, types::Requests, types::StorageBalances,
types::AssetFees, types::AssetMetadata, types::Assets, types::Balances,
types::BlackListedAccounts, types::Math, types::Network, types::Owners, types::Requests,
types::StorageBalances,
};
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::collections::LazyOption;
Expand All @@ -22,12 +23,14 @@ use near_sdk::{
log, near_bindgen, require, Gas, PanicOnDefault, Promise, PromiseResult,
};

use std::collections::HashSet;
use std::convert::TryFrom;
use std::convert::TryInto;
mod external;
use external::*;
mod accounting;
mod assertion;
mod blacklist_management;
mod coin_management;
mod estimate;
mod fee_management;
Expand Down Expand Up @@ -59,6 +62,7 @@ pub struct BtpTokenService {
serial_no: i128,
bmc: AccountId,
name: String,
blacklisted_accounts: BlackListedAccounts,

#[cfg(feature = "testable")]
pub message: LazyOption<Base64VecU8>,
Expand All @@ -80,7 +84,7 @@ impl BtpTokenService {

balances.add(&env::current_account_id(), &native_coin_id);
coins.add(&native_coin_id, &native_coin);

let blacklisted_accounts = BlackListedAccounts::new();
let mut coin_fees = CoinFees::new();
coin_fees.add(&native_coin_id);
Self {
Expand All @@ -95,6 +99,7 @@ impl BtpTokenService {
requests: Requests::new(),
bmc,
name: service_name,
blacklisted_accounts,

#[cfg(feature = "testable")]
message: LazyOption::new(b"message".to_vec(), None),
Expand Down
138 changes: 138 additions & 0 deletions rust/near/bsh/bts/tests/test_blacklist_management.rs
@@ -0,0 +1,138 @@
use std::{collections::HashSet, iter::FromIterator, result, str::FromStr};

use btp_common::errors::BshError;
use bts::{BtpTokenService, Coin};
use libraries::types::BTPAddress;
use near_sdk::{
env, serde_json::to_value, test_utils::test_env::alice, testing_env, AccountId, PromiseResult,
VMContext,
};
mod token;
use token::*;
pub mod accounts;
use accounts::*;

fn get_context(
input: Vec<u8>,
is_view: bool,
signer_account_id: AccountId,
attached_deposit: u128,
storage_usage: u64,
account_balance: u128,
) -> VMContext {
VMContext {
current_account_id: alice().to_string(),
signer_account_id: signer_account_id.to_string(),
signer_account_pk: vec![0, 1, 2],
predecessor_account_id: signer_account_id.to_string(),
input,
block_index: 0,
block_timestamp: 0,
account_balance,
account_locked_balance: 0,
storage_usage,
attached_deposit,
prepaid_gas: 10u64.pow(18),
random_seed: vec![0, 1, 2],
is_view,
output_data_receivers: vec![],
epoch_height: 19,
}
}

#[test]
fn add_user_to_blacklist() {
let context = |account_id: AccountId, deposit: u128| {
get_context(vec![], false, account_id, deposit, env::storage_usage(), 0)
};
testing_env!(context(alice(), 0));
let nativecoin = <Coin>::new(NATIVE_COIN.to_owned());
let mut contract = BtpTokenService::new(
"nativecoin".to_string(),
bmc(),
"0x1.near".into(),
nativecoin.clone(),
);

let users = vec![chuck(), charlie()];

contract.add_to_blacklist(users);
let users = contract.get_blacklisted_user();
let result: HashSet<_> = users.iter().collect();
let expected_users: Vec<AccountId> = vec![charlie(), chuck()];
let expected: HashSet<_> = expected_users.iter().collect();
assert_eq!(expected, result)
}

#[test]
fn remove_blacklisted_user_from_blacklist() {
let context = |account_id: AccountId, deposit: u128| {
get_context(vec![], false, account_id, deposit, env::storage_usage(), 0)
};
testing_env!(context(alice(), 0));
let nativecoin = <Coin>::new(NATIVE_COIN.to_owned());
let mut contract = BtpTokenService::new(
"nativecoin".to_string(),
bmc(),
"0x1.near".into(),
nativecoin.clone(),
);

let users = vec![chuck().clone(), charlie().clone()];

contract.add_to_blacklist(users.clone());
let users = contract.get_blacklisted_user();
let result: HashSet<_> = users.iter().collect();
let expected_users: Vec<AccountId> = vec![charlie(), chuck()];
let expected: HashSet<_> = expected_users.iter().collect();
assert_eq!(expected, result);

let users = vec![chuck().clone()];
let result = contract.remove_from_blacklist(users.clone());
match result {
Ok(()) => {
let result = contract.get_blacklisted_user().contains(&chuck());

assert_eq!(false, result)
}
Err(_) => todo!(),
}
}

#[test]
fn remove_non_blacklisted_user_from_blacklist() {
let context = |account_id: AccountId, deposit: u128| {
get_context(vec![], false, account_id, deposit, env::storage_usage(), 0)
};
testing_env!(context(alice(), 0));
let nativecoin = <Coin>::new(NATIVE_COIN.to_owned());
let mut contract = BtpTokenService::new(
"nativecoin".to_string(),
bmc(),
"0x1.near".into(),
nativecoin.clone(),
);

let users = vec![chuck().clone(), charlie().clone()];

contract.add_to_blacklist(users.clone());
let users = contract.get_blacklisted_user();
let result: HashSet<_> = users.iter().collect();
let expected_users: Vec<AccountId> = vec![charlie(), chuck()];
let expected: HashSet<_> = expected_users.iter().collect();
assert_eq!(expected, result);

let users = vec![carol().clone()];
let result = contract.remove_from_blacklist(users.clone());
match result {
Ok(()) => {}
Err(err) => {
assert_eq!(
BshError::BlacklistedUsers {
message: carol().to_string()
},
err
)
}
}
}