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

feat(its)!: full its coverage #199

Merged
merged 2 commits into from
Nov 18, 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
138 changes: 135 additions & 3 deletions move/its/sources/discovery.move
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ use std::ascii;
use std::type_name;
use sui::address;

const EUnsupportedMessageType: u64 = 0;
const EInvalidMessageType: u64 = 0;
/// ------
/// Errors
/// ------
#[error]
const EUnsupportedMessageType: vector<u8> =
b"the message type found is not supported";
#[error]
const EInvalidMessageType: vector<u8> =
b"can only get interchain transfer info for interchain transfers";

const MESSAGE_TYPE_INTERCHAIN_TRANSFER: u256 = 0;
const MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN: u256 = 1;
Expand Down Expand Up @@ -137,7 +144,7 @@ fun interchain_transfer_tx(its: &ITS, reader: &mut AbiReader): Transaction {
ascii::string(b"discovery"),
ascii::string(b"get_transaction"),
),
vector[discovery_arg, channel_id_arg ],
vector[discovery_arg, channel_id_arg],
vector[],
),
],
Expand Down Expand Up @@ -382,3 +389,128 @@ fun test_discovery_deploy_token() {
sui::test_utils::destroy(its);
sui::test_utils::destroy(discovery);
}

#[test]
fun test_interchain_transfer_info() {
let message_type = MESSAGE_TYPE_INTERCHAIN_TRANSFER;
let token_id = 1;
let source_address = b"source address";
let destination = @0x3.to_bytes();
let amount = 2;
let data = b"data";

let mut writer = abi::new_writer(6);
writer
.write_u256(message_type)
.write_u256(token_id)
.write_bytes(source_address)
.write_bytes(destination)
.write_u256(amount)
.write_bytes(data);

let (
resolved_token_id,
resolved_destination,
resolved_amount,
resolved_data,
) = interchain_transfer_info(writer.into_bytes());
assert!(resolved_token_id == token_id::from_u256(token_id));
assert!(resolved_destination == address::from_bytes(destination));
assert!(resolved_amount == (amount as u64));
assert!(resolved_data == data);
}

#[test]
#[expected_failure(abort_code = EInvalidMessageType)]
fun test_interchain_transfer_info_invalid_message_type() {
let message_type = MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN;
let token_id = @0x1234;
let name = b"name";
let symbol = b"symbol";
let decimals = 15;
let distributor = @0x0325;
let mut writer = abi::new_writer(6);
writer
.write_u256(message_type)
.write_u256(address::to_u256(token_id))
.write_bytes(name)
.write_bytes(symbol)
.write_u256(decimals)
.write_bytes(distributor.to_bytes());

interchain_transfer_info(writer.into_bytes());
}

#[test]
fun test_discovery_hub_message() {
let ctx = &mut sui::tx_context::dummy();
let mut its = its::its::create_for_testing(ctx);
let mut discovery = relayer_discovery::discovery::new(ctx);

register_transaction(&mut its, &mut discovery);

let token_id = @0x1234;
let source_address = b"source address";
let target_channel = @0x5678;
let amount = 1905;
let data = b"";
let mut writer = abi::new_writer(6);
writer
.write_u256(MESSAGE_TYPE_INTERCHAIN_TRANSFER)
.write_u256(address::to_u256(token_id))
.write_bytes(source_address)
.write_bytes(target_channel.to_bytes())
.write_u256(amount)
.write_bytes(data);
let inner = writer.into_bytes();
writer = abi::new_writer(3);
writer
.write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB)
.write_bytes(b"source_chain")
.write_bytes(inner);
let payload = writer.into_bytes();

let type_arg = std::type_name::get<RelayerDiscovery>();
its.add_registered_coin_type_for_testing(
its::token_id::from_address(token_id),
type_arg,
);
let tx_block = call_info(&its, payload);

assert!(tx_block == call_info(&its, payload));
assert!(tx_block.is_final() && tx_block.move_calls().length() == 1);

let call_info = tx_block.move_calls().pop_back();

assert!(
call_info.function().package_id_from_function() == package_id<ITS>(),
);
assert!(call_info.function().module_name() == ascii::string(b"its"));
assert!(
call_info.function().name() == ascii::string(b"receive_interchain_transfer"),
);
let mut arg = vector[0];
arg.append(object::id_address(&its).to_bytes());

let arguments = vector[arg, vector[2], vector[0, 6]];
assert!(call_info.arguments() == arguments);
assert!(call_info.type_arguments() == vector[type_arg.into_string()]);

sui::test_utils::destroy(its);
sui::test_utils::destroy(discovery);
}

#[test]
#[expected_failure(abort_code = EUnsupportedMessageType)]
fun test_call_info_unsupported_message_type() {
let ctx = &mut sui::tx_context::dummy();
let its = its::its::create_for_testing(ctx);

let mut writer = abi::new_writer(1);
writer.write_u256(5);
let payload = writer.into_bytes();

call_info(&its, payload);

sui::test_utils::destroy(its);
}
42 changes: 41 additions & 1 deletion move/its/sources/its.move
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ fun version_control(): VersionControl {
b"mint_to_as_distributor",
b"burn_as_distributor",
b"set_trusted_addresses",
b"remove_trusted_addresses",
b"register_transaction",
].map!(|function_name| function_name.to_ascii_string()),
])
Expand Down Expand Up @@ -822,8 +823,47 @@ fun test_set_trusted_address() {
trusted_addresses,
);

set_trusted_addresses(&mut its, &owner_cap, trusted_addresses);
its.set_trusted_addresses(&owner_cap, trusted_addresses);
its.remove_trusted_addresses(&owner_cap, trusted_chains);

sui::test_utils::destroy(its);
sui::test_utils::destroy(owner_cap);
}

#[test]
fun test_init() {
let mut ts = sui::test_scenario::begin(@0x0);

init(ts.ctx());
ts.next_tx(@0x0);

let owner_cap = ts.take_from_sender<OwnerCap>();
let its = ts.take_shared<ITS>();
ts.return_to_sender(owner_cap);
sui::test_scenario::return_shared(its);
ts.end();
}

#[test]
fun test_registered_coin_type() {
let ctx = &mut tx_context::dummy();
let mut its = create_for_testing(ctx);
let token_id = its::token_id::from_address(@0x1);
its.add_registered_coin_type_for_testing(
token_id,
std::type_name::get<COIN>(),
);
its.registered_coin_type(token_id);

sui::test_utils::destroy(its);
}

#[test]
fun test_channel_address() {
let ctx = &mut tx_context::dummy();
let its = create_for_testing(ctx);

its.channel_address();

sui::test_utils::destroy(its);
}
22 changes: 17 additions & 5 deletions move/its/sources/types/address_tracker.move
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ use sui::table::{Self, Table};
// Errors
// ------
#[error]
const ENoAddress: vector<u8> = b"attempt to borrow a trusted address but it's not registered";
const ENoAddress: vector<u8> =
b"attempt to borrow a trusted address but it's not registered";
#[error]
const EEmptyChainName: vector<u8> = b"empty trusted chain name is unsupported";
#[error]
const EEmptyTrustedAddress: vector<u8> = b"empty trusted address is unsupported";
const EEmptyTrustedAddress: vector<u8> =
b"empty trusted address is unsupported";

/// The interchain address tracker stores the trusted addresses for each chain.
public struct InterchainAddressTracker has store {
Expand All @@ -38,7 +40,7 @@ public fun is_trusted_address(
chain_name: String,
addr: String,
): bool {
trusted_address(self, chain_name) == &addr
self.trusted_addresses.contains(chain_name) && self.trusted_addresses[chain_name] == addr
}

// -----------------
Expand Down Expand Up @@ -141,7 +143,6 @@ fun test_set_trusted_address_empty_trusted_address() {
sui::test_utils::destroy(self);
}


#[test]
fun test_remove_trusted_address() {
let ctx = &mut sui::tx_context::dummy();
Expand All @@ -155,7 +156,6 @@ fun test_remove_trusted_address() {
sui::test_utils::destroy(self);
}


#[test]
#[expected_failure(abort_code = EEmptyChainName)]
fun test_remove_trusted_address_empty_chain_name() {
Expand All @@ -167,3 +167,15 @@ fun test_remove_trusted_address_empty_chain_name() {

sui::test_utils::destroy(self);
}

#[test]
#[expected_failure(abort_code = ENoAddress)]
fun test_trusted_address_no_address() {
let ctx = &mut sui::tx_context::dummy();
let self = new(ctx);
let chain = std::ascii::string(b"");

self.trusted_address(chain);

sui::test_utils::destroy(self);
}
51 changes: 51 additions & 0 deletions move/its/sources/types/coin_management.move
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,54 @@ fun test_give_coin() {
sui::test_utils::destroy(management2);
sui::test_utils::destroy(clock);
}

#[test]
#[expected_failure(abort_code = EDistributorNeedsTreasuryCap)]
fun test_add_distributor_no_capability() {
let mut management = new_locked<COIN_MANAGEMENT>();
let distributor = @0x1;

management.add_distributor(distributor);

sui::test_utils::destroy(management);
}

#[test]
fun test_add_operator() {
let mut management = new_locked<COIN_MANAGEMENT>();
let operator = @0x1;

management.add_operator(operator);

sui::test_utils::destroy(management);
}

#[test]
fun test_set_flow_limit() {
let ctx = &mut sui::tx_context::dummy();

let mut management = new_locked<COIN_MANAGEMENT>();
let channel = axelar_gateway::channel::new(ctx);

management.add_operator(channel.to_address());
management.set_flow_limit(&channel, 1);

sui::test_utils::destroy(management);
sui::test_utils::destroy(channel);
}

#[test]
#[expected_failure(abort_code = ENotOperator)]
fun test_set_flow_limit_not_operator() {
let ctx = &mut sui::tx_context::dummy();

let mut management = new_locked<COIN_MANAGEMENT>();
let channel = axelar_gateway::channel::new(ctx);
let operator = @0x1;

management.add_operator(operator);
management.set_flow_limit(&channel, 1);

sui::test_utils::destroy(management);
sui::test_utils::destroy(channel);
}
Loading