Module 0xb::message
- Struct
BridgeMessage
- Struct
BridgeMessageKey
- Struct
TokenTransferPayload
- Struct
EmergencyOp
- Struct
Blocklist
- Struct
UpdateBridgeLimit
- Struct
UpdateAssetPrice
- Struct
AddTokenOnSui
- Struct
ParsedTokenTransferMessage
- Constants
- Function
extract_token_bridge_payload
- Function
extract_emergency_op_payload
- Function
extract_blocklist_payload
- Function
extract_update_bridge_limit
- Function
extract_update_asset_price
- Function
extract_add_tokens_on_sui
- Function
serialize_message
- Function
create_token_bridge_message
- Function
create_emergency_op_message
- Function
create_blocklist_message
- Function
create_update_bridge_limit_message
- Function
create_update_asset_price_message
- Function
create_add_tokens_on_sui_message
- Function
create_key
- Function
key
- Function
message_version
- Function
message_type
- Function
seq_num
- Function
source_chain
- Function
payload
- Function
token_target_chain
- Function
token_target_address
- Function
token_type
- Function
token_amount
- Function
emergency_op_type
- Function
blocklist_type
- Function
blocklist_validator_addresses
- Function
update_bridge_limit_payload_sending_chain
- Function
update_bridge_limit_payload_receiving_chain
- Function
update_bridge_limit_payload_limit
- Function
update_asset_price_payload_token_id
- Function
update_asset_price_payload_new_price
- Function
is_native
- Function
token_ids
- Function
token_type_names
- Function
token_prices
- Function
emergency_op_pause
- Function
emergency_op_unpause
- Function
required_voting_power
- Function
to_parsed_token_transfer_message
- Function
reverse_bytes
- Function
peel_u64_be
use 0x1::ascii;
use 0x1::vector;
use 0x2::bcs;
use 0xb::chain_ids;
use 0xb::message_types;
Struct BridgeMessage
struct BridgeMessage has copy, drop, store
Struct BridgeMessageKey
struct BridgeMessageKey has copy, drop, store
Fields
- source_chain: u8
- message_type: u8
- bridge_seq_num: u64
Struct TokenTransferPayload
struct TokenTransferPayload has drop
Struct EmergencyOp
struct EmergencyOp has drop
Fields
- op_type: u8
Struct Blocklist
struct Blocklist has drop
Struct UpdateBridgeLimit
struct UpdateBridgeLimit has drop
Fields
- receiving_chain: u8
- sending_chain: u8
- limit: u64
Struct UpdateAssetPrice
struct UpdateAssetPrice has drop
Fields
- token_id: u8
- new_price: u64
Struct AddTokenOnSui
struct AddTokenOnSui has drop
Fields
- native_token: bool
- token_ids: vector<u8>
- token_type_names: vector<ascii::String>
- token_prices: vector<u64>
Struct ParsedTokenTransferMessage
struct ParsedTokenTransferMessage has drop
Fields
- message_version: u8
- seq_num: u64
- source_chain: u8
- payload: vector<u8>
- parsed_payload: message::TokenTransferPayload
Constants
const CURRENT_MESSAGE_VERSION: u8 = 1;
const ECDSA_ADDRESS_LENGTH: u64 = 20;
const EEmptyList: u64 = 2;
const EInvalidAddressLength: u64 = 1;
const EInvalidEmergencyOpType: u64 = 4;
const EInvalidMessageType: u64 = 3;
const EInvalidPayloadLength: u64 = 5;
const EMustBeTokenMessage: u64 = 6;
const ETrailingBytes: u64 = 0;
const PAUSE: u8 = 0;
const UNPAUSE: u8 = 1;
Function extract_token_bridge_payload
public fun extract_token_bridge_payload(message: &message::BridgeMessage): message::TokenTransferPayload
Implementation
public fun extract_token_bridge_payload(message: &BridgeMessage): TokenTransferPayload {
let mut bcs = bcs::new(message.payload);
let sender_address = bcs.peel_vec_u8();
let target_chain = bcs.peel_u8();
let target_address = bcs.peel_vec_u8();
let token_type = bcs.peel_u8();
let amount = peel_u64_be(&mut bcs);
chain_ids::assert_valid_chain_id(target_chain);
assert!(bcs.into_remainder_bytes().is_empty(), ETrailingBytes);
TokenTransferPayload {
sender_address,
target_chain,
target_address,
token_type,
amount
}
}
Function extract_emergency_op_payload
Emergency op payload is just a single byte
public fun extract_emergency_op_payload(message: &message::BridgeMessage): message::EmergencyOp
Implementation
public fun extract_emergency_op_payload(message: &BridgeMessage): EmergencyOp {
assert!(message.payload.length() == 1, ETrailingBytes);
EmergencyOp { op_type: message.payload[0] }
}
Function extract_blocklist_payload
public fun extract_blocklist_payload(message: &message::BridgeMessage): message::Blocklist
Implementation
public fun extract_blocklist_payload(message: &BridgeMessage): Blocklist {
// blocklist payload should consist of one byte blocklist type, and list of 20 bytes evm addresses
// derived from ECDSA public keys
let mut bcs = bcs::new(message.payload);
let blocklist_type = bcs.peel_u8();
let mut address_count = bcs.peel_u8();
assert!(address_count != 0, EEmptyList);
let mut validator_eth_addresses = vector[];
while (address_count > 0) {
let (mut address, mut i) = (vector[], 0);
while (i < ECDSA_ADDRESS_LENGTH) {
address.push_back(bcs.peel_u8());
i = i + 1;
};
validator_eth_addresses.push_back(address);
address_count = address_count - 1;
};
assert!(bcs.into_remainder_bytes().is_empty(), ETrailingBytes);
Blocklist {
blocklist_type,
validator_eth_addresses
}
}
Function extract_update_bridge_limit
public fun extract_update_bridge_limit(message: &message::BridgeMessage): message::UpdateBridgeLimit
Implementation
public fun extract_update_bridge_limit(message: &BridgeMessage): UpdateBridgeLimit {
let mut bcs = bcs::new(message.payload);
let sending_chain = bcs.peel_u8();
let limit = peel_u64_be(&mut bcs);
chain_ids::assert_valid_chain_id(sending_chain);
assert!(bcs.into_remainder_bytes().is_empty(), ETrailingBytes);
UpdateBridgeLimit {
receiving_chain: message.source_chain,
sending_chain,
limit
}
}
Function extract_update_asset_price
public fun extract_update_asset_price(message: &message::BridgeMessage): message::UpdateAssetPrice
Implementation
public fun extract_update_asset_price(message: &BridgeMessage): UpdateAssetPrice {
let mut bcs = bcs::new(message.payload);
let token_id = bcs.peel_u8();
let new_price = peel_u64_be(&mut bcs);
assert!(bcs.into_remainder_bytes().is_empty(), ETrailingBytes);
UpdateAssetPrice {
token_id,
new_price
}
}
Function extract_add_tokens_on_sui
public fun extract_add_tokens_on_sui(message: &message::BridgeMessage): message::AddTokenOnSui
Implementation
public fun extract_add_tokens_on_sui(message: &BridgeMessage): AddTokenOnSui {
let mut bcs = bcs::new(message.payload);
let native_token = bcs.peel_bool();
let token_ids = bcs.peel_vec_u8();
let token_type_names_bytes = bcs.peel_vec_vec_u8();
let token_prices = bcs.peel_vec_u64();
let mut n = 0;
let mut token_type_names = vector[];
while (n < token_type_names_bytes.length()){
token_type_names.push_back(ascii::string(*token_type_names_bytes.borrow(n)));
n = n + 1;
};
assert!(bcs.into_remainder_bytes().is_empty(), ETrailingBytes);
AddTokenOnSui {
native_token,
token_ids,
token_type_names,
token_prices
}
}
Function serialize_message
public fun serialize_message(message: message::BridgeMessage): vector<u8>
Implementation
public fun serialize_message(message: BridgeMessage): vector<u8> {
let BridgeMessage {
message_type,
message_version,
seq_num,
source_chain,
payload
} = message;
let mut message = vector[
message_type,
message_version,
];
// bcs serializes u64 as 8 bytes
message.append(reverse_bytes(bcs::to_bytes(&seq_num)));
message.push_back(source_chain);
message.append(payload);
message
}
Function create_token_bridge_message
Token Transfer Message Format: [message_type: u8] [version:u8] [nonce:u64] [source_chain: u8] [sender_address_length:u8] [sender_address: byte[]] [target_chain:u8] [target_address_length:u8] [target_address: byte[]] [token_type:u8] [amount:u64]
public fun create_token_bridge_message(source_chain: u8, seq_num: u64, sender_address: vector<u8>, target_chain: u8, target_address: vector<u8>, token_type: u8, amount: u64): message::BridgeMessage
Implementation
public fun create_token_bridge_message(
source_chain: u8,
seq_num: u64,
sender_address: vector<u8>,
target_chain: u8,
target_address: vector<u8>,
token_type: u8,
amount: u64
): BridgeMessage {
chain_ids::assert_valid_chain_id(source_chain);
chain_ids::assert_valid_chain_id(target_chain);
let mut payload = vector[];
// sender address should be less than 255 bytes so can fit into u8
payload.push_back((vector::length(&sender_address) as u8));
payload.append(sender_address);
payload.push_back(target_chain);
// target address should be less than 255 bytes so can fit into u8
payload.push_back((vector::length(&target_address) as u8));
payload.append(target_address);
payload.push_back(token_type);
// bcs serialzies u64 as 8 bytes
payload.append(reverse_bytes(bcs::to_bytes(&amount)));
assert!(vector::length(&payload) == 64, EInvalidPayloadLength);
BridgeMessage {
message_type: message_types::token(),
message_version: CURRENT_MESSAGE_VERSION,
seq_num,
source_chain,
payload,
}
}
Function create_emergency_op_message
Emergency Op Message Format: [message_type: u8] [version:u8] [nonce:u64] [chain_id: u8] [op_type: u8]
public fun create_emergency_op_message(source_chain: u8, seq_num: u64, op_type: u8): message::BridgeMessage
Implementation
public fun create_emergency_op_message(
source_chain: u8,
seq_num: u64,
op_type: u8,
): BridgeMessage {
chain_ids::assert_valid_chain_id(source_chain);
BridgeMessage {
message_type: message_types::emergency_op(),
message_version: CURRENT_MESSAGE_VERSION,
seq_num,
source_chain,
payload: vector[op_type],
}
}
Function create_blocklist_message
Blocklist Message Format: [message_type: u8] [version:u8] [nonce:u64] [chain_id: u8] [blocklist_type: u8] [validator_length: u8] [validator_ecdsa_addresses: byte[][]]
public fun create_blocklist_message(source_chain: u8, seq_num: u64, blocklist_type: u8, validator_ecdsa_addresses: vector<vector<u8>>): message::BridgeMessage
Implementation
public fun create_blocklist_message(
source_chain: u8,
seq_num: u64,
// 0: block, 1: unblock
blocklist_type: u8,
validator_ecdsa_addresses: vector<vector<u8>>,
): BridgeMessage {
chain_ids::assert_valid_chain_id(source_chain);
let address_length = validator_ecdsa_addresses.length();
let mut payload = vector[blocklist_type, (address_length as u8)];
let mut i = 0;
while (i < address_length) {
let address = validator_ecdsa_addresses[i];
assert!(address.length() == ECDSA_ADDRESS_LENGTH, EInvalidAddressLength);
payload.append(address);
i = i + 1;
};
BridgeMessage {
message_type: message_types::committee_blocklist(),
message_version: CURRENT_MESSAGE_VERSION,
seq_num,
source_chain,
payload,
}
}
Function create_update_bridge_limit_message
Update bridge limit Message Format: [message_type: u8] [version:u8] [nonce:u64] [receiving_chain_id: u8] [sending_chain_id: u8] [new_limit: u64]
public fun create_update_bridge_limit_message(receiving_chain: u8, seq_num: u64, sending_chain: u8, new_limit: u64): message::BridgeMessage
Implementation
public fun create_update_bridge_limit_message(
receiving_chain: u8,
seq_num: u64,
sending_chain: u8,
new_limit: u64,
): BridgeMessage {
chain_ids::assert_valid_chain_id(receiving_chain);
chain_ids::assert_valid_chain_id(sending_chain);
let mut payload = vector[sending_chain];
payload.append(reverse_bytes(bcs::to_bytes(&new_limit)));
BridgeMessage {
message_type: message_types::update_bridge_limit(),
message_version: CURRENT_MESSAGE_VERSION,
seq_num,
source_chain: receiving_chain,
payload,
}
}
Function create_update_asset_price_message
Update asset price message [message_type: u8] [version:u8] [nonce:u64] [chain_id: u8] [token_id: u8] [new_price:u64]
public fun create_update_asset_price_message(token_id: u8, source_chain: u8, seq_num: u64, new_price: u64): message::BridgeMessage
Implementation
public fun create_update_asset_price_message(
token_id: u8,
source_chain: u8,
seq_num: u64,
new_price: u64,
): BridgeMessage {
chain_ids::assert_valid_chain_id(source_chain);
let mut payload = vector[token_id];
payload.append(reverse_bytes(bcs::to_bytes(&new_price)));
BridgeMessage {
message_type: message_types::update_asset_price(),
message_version: CURRENT_MESSAGE_VERSION,
seq_num,
source_chain,
payload,
}
}
Function create_add_tokens_on_sui_message
Update Sui token message
[message_type:u8]
[version:u8]
[nonce:u64]
[chain_id: u8]
[native_token:bool]
[token_ids:vector
public fun create_add_tokens_on_sui_message(source_chain: u8, seq_num: u64, native_token: bool, token_ids: vector<u8>, type_names: vector<ascii::String>, token_prices: vector<u64>): message::BridgeMessage
Implementation
public fun create_add_tokens_on_sui_message(
source_chain: u8,
seq_num: u64,
native_token: bool,
token_ids: vector<u8>,
type_names: vector<String>,
token_prices: vector<u64>,
): BridgeMessage {
chain_ids::assert_valid_chain_id(source_chain);
let mut payload = bcs::to_bytes(&native_token);
payload.append(bcs::to_bytes(&token_ids));
payload.append(bcs::to_bytes(&type_names));
payload.append(bcs::to_bytes(&token_prices));
BridgeMessage {
message_type: message_types::add_tokens_on_sui(),
message_version: CURRENT_MESSAGE_VERSION,
seq_num,
source_chain,
payload,
}
}
Function create_key
public fun create_key(source_chain: u8, message_type: u8, bridge_seq_num: u64): message::BridgeMessageKey
Implementation
public fun create_key(source_chain: u8, message_type: u8, bridge_seq_num: u64): BridgeMessageKey {
BridgeMessageKey { source_chain, message_type, bridge_seq_num }
}
Function key
public fun key(self: &message::BridgeMessage): message::BridgeMessageKey
Implementation
public fun key(self: &BridgeMessage): BridgeMessageKey {
create_key(self.source_chain, self.message_type, self.seq_num)
}
Function message_version
public fun message_version(self: &message::BridgeMessage): u8
Implementation
public fun message_version(self: &BridgeMessage): u8 {
self.message_version
}
Function message_type
public fun message_type(self: &message::BridgeMessage): u8
Implementation
public fun message_type(self: &BridgeMessage): u8 {
self.message_type
}
Function seq_num
public fun seq_num(self: &message::BridgeMessage): u64
Implementation
public fun seq_num(self: &BridgeMessage): u64 {
self.seq_num
}
Function source_chain
public fun source_chain(self: &message::BridgeMessage): u8
Implementation
public fun source_chain(self: &BridgeMessage): u8 {
self.source_chain
}
Function payload
public fun payload(self: &message::BridgeMessage): vector<u8>
Implementation
public fun payload(self: &BridgeMessage): vector<u8> {
self.payload
}
Function token_target_chain
public fun token_target_chain(self: &message::TokenTransferPayload): u8
Implementation
public fun token_target_chain(self: &TokenTransferPayload): u8 {
self.target_chain
}
Function token_target_address
public fun token_target_address(self: &message::TokenTransferPayload): vector<u8>
Implementation
public fun token_target_address(self: &TokenTransferPayload): vector<u8> {
self.target_address
}
Function token_type
public fun token_type(self: &message::TokenTransferPayload): u8
Implementation
public fun token_type(self: &TokenTransferPayload): u8 {
self.token_type
}
Function token_amount
public fun token_amount(self: &message::TokenTransferPayload): u64
Implementation
public fun token_amount(self: &TokenTransferPayload): u64 {
self.amount
}
Function emergency_op_type
public fun emergency_op_type(self: &message::EmergencyOp): u8
Implementation
public fun emergency_op_type(self: &EmergencyOp): u8 {
self.op_type
}
Function blocklist_type
public fun blocklist_type(self: &message::Blocklist): u8
Implementation
public fun blocklist_type(self: &Blocklist): u8 {
self.blocklist_type
}
Function blocklist_validator_addresses
public fun blocklist_validator_addresses(self: &message::Blocklist): &vector<vector<u8>>
Implementation
public fun blocklist_validator_addresses(self: &Blocklist): &vector<vector<u8>> {
&self.validator_eth_addresses
}
Function update_bridge_limit_payload_sending_chain
public fun update_bridge_limit_payload_sending_chain(self: &message::UpdateBridgeLimit): u8
Implementation
public fun update_bridge_limit_payload_sending_chain(self: &UpdateBridgeLimit): u8 {
self.sending_chain
}
Function update_bridge_limit_payload_receiving_chain
public fun update_bridge_limit_payload_receiving_chain(self: &message::UpdateBridgeLimit): u8
Implementation
public fun update_bridge_limit_payload_receiving_chain(self: &UpdateBridgeLimit): u8 {
self.receiving_chain
}
Function update_bridge_limit_payload_limit
public fun update_bridge_limit_payload_limit(self: &message::UpdateBridgeLimit): u64
Implementation
public fun update_bridge_limit_payload_limit(self: &UpdateBridgeLimit): u64 {
self.limit
}
Function update_asset_price_payload_token_id
public fun update_asset_price_payload_token_id(self: &message::UpdateAssetPrice): u8
Implementation
public fun update_asset_price_payload_token_id(self: &UpdateAssetPrice): u8 {
self.token_id
}
Function update_asset_price_payload_new_price
public fun update_asset_price_payload_new_price(self: &message::UpdateAssetPrice): u64
Implementation
public fun update_asset_price_payload_new_price(self: &UpdateAssetPrice): u64 {
self.new_price
}
Function is_native
public fun is_native(self: &message::AddTokenOnSui): bool
Implementation
public fun is_native(self: &AddTokenOnSui): bool {
self.native_token
}
Function token_ids
public fun token_ids(self: &message::AddTokenOnSui): vector<u8>
Implementation
public fun token_ids(self: &AddTokenOnSui): vector<u8> {
self.token_ids
}
Function token_type_names
public fun token_type_names(self: &message::AddTokenOnSui): vector<ascii::String>
Implementation
public fun token_type_names(self: &AddTokenOnSui): vector<String> {
self.token_type_names
}
Function token_prices
public fun token_prices(self: &message::AddTokenOnSui): vector<u64>
Implementation
public fun token_prices(self: &AddTokenOnSui): vector<u64> {
self.token_prices
}
Function emergency_op_pause
public fun emergency_op_pause(): u8
Implementation
public fun emergency_op_pause(): u8 {
PAUSE
}
Function emergency_op_unpause
public fun emergency_op_unpause(): u8
Implementation
public fun emergency_op_unpause(): u8 {
UNPAUSE
}
Function required_voting_power
Return the required signature threshold for the message, values are voting power in the scale of 10000
public fun required_voting_power(self: &message::BridgeMessage): u64
Implementation
public fun required_voting_power(self: &BridgeMessage): u64 {
let message_type = message_type(self);
if (message_type == message_types::token()) {
3334
} else if (message_type == message_types::emergency_op()) {
let payload = extract_emergency_op_payload(self);
if (payload.op_type == PAUSE) {
450
} else if (payload.op_type == UNPAUSE) {
5001
} else {
abort EInvalidEmergencyOpType
}
} else if (message_type == message_types::committee_blocklist()) {
5001
} else if (message_type == message_types::update_asset_price()) {
5001
} else if (message_type == message_types::update_bridge_limit()) {
5001
} else if (message_type == message_types::add_tokens_on_sui()) {
5001
} else {
abort EInvalidMessageType
}
}
Function to_parsed_token_transfer_message
public fun to_parsed_token_transfer_message(message: &message::BridgeMessage): message::ParsedTokenTransferMessage
Implementation
public fun to_parsed_token_transfer_message(
message: &BridgeMessage,
): ParsedTokenTransferMessage {
assert!(message.message_type() == message_types::token(), EMustBeTokenMessage);
let payload = message.extract_token_bridge_payload();
ParsedTokenTransferMessage {
message_version: message.message_version(),
seq_num: message.seq_num(),
source_chain: message.source_chain(),
payload: message.payload(),
parsed_payload: payload,
}
}
Function reverse_bytes
fun reverse_bytes(bytes: vector<u8>): vector<u8>
Implementation
fun reverse_bytes(mut bytes: vector<u8>): vector<u8> {
vector::reverse(&mut bytes);
bytes
}
Function peel_u64_be
fun peel_u64_be(bcs: &mut bcs::BCS): u64
Implementation
fun peel_u64_be(bcs: &mut BCS): u64 {
let (mut value, mut i) = (0u64, 64u8);
while (i > 0) {
i = i - 8;
let byte = (bcs::peel_u8(bcs) as u64);
value = value + (byte << i);
};
value
}