Skip to content

Commit

Permalink
refactor: make global id structured (#109)
Browse files Browse the repository at this point in the history
  • Loading branch information
cgorenflo authored Sep 20, 2023
1 parent 88d43ec commit 9414bcd
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 90 deletions.
8 changes: 3 additions & 5 deletions .github/workflows/basic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ on:
- main
- releases/**

env:
RUSTFLAGS: -D warnings -A deprecated --cfg tracing_unstable

name: Basic

jobs:
Expand Down Expand Up @@ -40,6 +37,7 @@ jobs:
command: test
args: --locked
env:
RUSTFLAGS: --cfg tracing_unstable
RUST_BACKTRACE: 1

cosmwasm-compilation:
Expand Down Expand Up @@ -67,7 +65,7 @@ jobs:
command: wasm
args: --locked --workspace --exclude ampd
env:
RUSTFLAGS: -D warnings -A deprecated --cfg tracing_unstable -C link-arg=-s
RUSTFLAGS: --cfg tracing_unstable -C link-arg=-s

lints:
name: Lints
Expand Down Expand Up @@ -114,7 +112,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: clippy
args: -- -D warnings
args: -- -D warnings -A deprecated

- name: Check Diff
# fails if any changes not committed
Expand Down
2 changes: 1 addition & 1 deletion contracts/connection-router/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ pub mod execute {
});
}

if msgs.iter().any(|msg| msg.source_chain != source_chain.name) {
if msgs.iter().any(|msg| msg.uid.chain != source_chain.name) {
return Err(ContractError::WrongSourceChain);
}

Expand Down
4 changes: 2 additions & 2 deletions contracts/connection-router/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ impl From<ChainUnfrozen> for Event {
impl From<NewMessage> for Vec<Attribute> {
fn from(other: NewMessage) -> Self {
vec![
("id", other.id_on_chain).into(),
("source_chain", other.source_chain).into(),
("id", other.uid.id).into(),
("source_chain", other.uid.chain).into(),
("source_addresses", other.source_address.deref()).into(),
("destination_chain", other.destination_chain).into(),
("destination_addresses", other.destination_address.deref()).into(),
Expand Down
61 changes: 26 additions & 35 deletions contracts/connection-router/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use error_stack::{bail, Report, ResultExt};

use axelar_wasm_std::nonempty;

use crate::types::GlobalMessageId;
use crate::types::CrossChainUid;
use crate::{
msg,
types::{ChainEndpoint, ChainName, MessageID, ID_SEPARATOR},
Expand Down Expand Up @@ -84,31 +84,23 @@ impl<'a> IndexList<ChainEndpoint> for ChainEndpointIndexes<'a> {

#[cw_serde]
pub struct NewMessage {
pub id_on_chain: MessageID, // unique per chain
pub uid: CrossChainUid,
pub destination_address: Address,
pub destination_chain: ChainName,
pub source_chain: ChainName,
pub source_address: Address,
pub payload_hash: HexBinary,
}

impl NewMessage {
/// Returns a globally unique message id.
pub fn global_id(&self) -> GlobalMessageId {
GlobalMessageId::new(self.source_chain.clone(), self.id_on_chain.clone())
}
}

/// temporary conversion until [Message] is removed
impl TryFrom<NewMessage> for Message {
type Error = ContractError;

fn try_from(msg: NewMessage) -> Result<Self, Self::Error> {
Ok(Message {
id: format!("{}", msg.global_id()).parse()?,
id: format!("{}", msg.uid).parse()?,
destination_address: msg.destination_address.to_string(),
destination_chain: msg.destination_chain,
source_chain: msg.source_chain,
source_chain: msg.uid.chain,
source_address: msg.source_address.to_string(),
payload_hash: msg.payload_hash,
})
Expand All @@ -130,10 +122,12 @@ impl TryFrom<Message> for NewMessage {
}

Ok(NewMessage {
id_on_chain: id.parse()?,
uid: CrossChainUid {
id: id.parse()?,
chain: msg.source_chain,
},
destination_address: msg.destination_address.parse()?,
destination_chain: msg.destination_chain,
source_chain: msg.source_chain,
source_address: msg.source_address.parse()?,
payload_hash: msg.payload_hash,
})
Expand Down Expand Up @@ -249,46 +243,43 @@ impl TryFrom<String> for Address {
#[cfg(test)]
mod tests {
use crate::state::NewMessage;
use crate::types::CrossChainUid;
use cosmwasm_std::to_vec;
use hex;
use sha3::{Digest, Sha3_256};

#[test]
fn create_correct_global_message_id() {
let msg = NewMessage {
id_on_chain: "hash:id".to_string().parse().unwrap(),
source_chain: "source_chain".to_string().parse().unwrap(),
source_address: "source_address".parse().unwrap(),
destination_chain: "destination_chain".parse().unwrap(),
destination_address: "destination_address".parse().unwrap(),
payload_hash: [1; 32].into(),
};
let msg = dummy_message();

assert_eq!(
msg.global_id().to_string(),
"source_chain:hash:id".to_string()
);
assert_eq!(msg.uid.to_string(), "chain:hash:index".to_string());
}

#[test]
// Any modifications to the Message struct fields or their types
// will cause this test to fail, indicating that a migration is needed.
fn test_message_struct_unchanged() {
let expected_message_hash =
"5f3a7dd295d833e5846820cd394fed714da1b45a8c372f73ec8ad8ec6aef9a0d";
"cf6a6e654af0d60891b91cb014b1c12c7d2d95edd5f3cca54125d8a9917b240e";

let msg = NewMessage {
id_on_chain: "hash:index".parse().unwrap(),
source_chain: "chain".parse().unwrap(),
source_address: "source_address".parse().unwrap(),
destination_chain: "destination_chain".parse().unwrap(),
destination_address: "destination_address".parse().unwrap(),
payload_hash: [1; 32].into(),
};
let msg = dummy_message();

assert_eq!(
hex::encode(Sha3_256::digest(&to_vec(&msg).unwrap())),
expected_message_hash
);
}

fn dummy_message() -> NewMessage {
NewMessage {
uid: CrossChainUid {
id: "hash:index".parse().unwrap(),
chain: "chain".parse().unwrap(),
},
source_address: "source_address".parse().unwrap(),
destination_chain: "destination_chain".parse().unwrap(),
destination_address: "destination_address".parse().unwrap(),
payload_hash: [1; 32].into(),
}
}
}
56 changes: 17 additions & 39 deletions contracts/connection-router/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ impl Deref for MessageID {
}
}

impl fmt::Display for MessageID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
impl Display for MessageID {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
Expand All @@ -81,63 +81,38 @@ impl KeyDeserialize for MessageID {
}
}

/// cosmwasm cannot serialize tuples, so we need to convert [GlobalMessageId] into a struct
#[cw_serde]
struct GlobalMessageIdSerde {
chain_name: ChainName,
message_id: MessageID,
}

/// cosmwasm cannot serialize tuples, so we need to convert [CrossChainUid] into a struct
#[cw_serde]
#[serde(from = "GlobalMessageIdSerde", into = "GlobalMessageIdSerde")]
pub struct GlobalMessageId(ChainName, MessageID);

impl From<GlobalMessageId> for GlobalMessageIdSerde {
fn from(other: GlobalMessageId) -> Self {
Self {
chain_name: other.0,
message_id: other.1,
}
}
}

impl From<GlobalMessageIdSerde> for GlobalMessageId {
fn from(other: GlobalMessageIdSerde) -> Self {
Self(other.chain_name, other.message_id)
}
}

impl GlobalMessageId {
pub fn new(chain_name: ChainName, message_id: MessageID) -> Self {
Self(chain_name, message_id)
}
pub struct CrossChainUid {
pub chain: ChainName,
pub id: MessageID,
}

impl Display for GlobalMessageId {
impl Display for CrossChainUid {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}{}{}", &self.0, ID_SEPARATOR, &self.1)
write!(f, "{}{}{}", &self.chain, ID_SEPARATOR, &self.id)
}
}

impl PrimaryKey<'_> for GlobalMessageId {
impl PrimaryKey<'_> for CrossChainUid {
type Prefix = ChainName;
type SubPrefix = ();
type Suffix = MessageID;
type SuperSuffix = (ChainName, MessageID);

fn key(&self) -> Vec<Key> {
let mut keys = self.0.key();
keys.extend(self.1.key());
let mut keys = self.chain.key();
keys.extend(self.id.key());
keys
}
}

impl KeyDeserialize for GlobalMessageId {
impl KeyDeserialize for CrossChainUid {
type Output = Self;

fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
let (chain, id) = <(ChainName, MessageID)>::from_vec(value)?;
Ok(GlobalMessageId(chain, id))
Ok(CrossChainUid { chain, id })
}
}

Expand Down Expand Up @@ -309,7 +284,10 @@ mod tests {

#[test]
fn serialize_global_message_id() {
let id = GlobalMessageId::new("ethereum".parse().unwrap(), "hash:id".parse().unwrap());
let id = CrossChainUid {
chain: "ethereum".parse().unwrap(),
id: "hash:id".parse().unwrap(),
};

let serialized = serde_json::to_string(&id).unwrap();
assert_eq!(id, serde_json::from_str(&serialized).unwrap());
Expand Down
10 changes: 5 additions & 5 deletions contracts/connection-router/tests/mock.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use connection_router::state::NewMessage;
use connection_router::types::GlobalMessageId;
use connection_router::types::CrossChainUid;
use connection_router::ContractError;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult};
use cw_multi_test::{App, ContractWrapper, Executor};
use cw_storage_plus::Map;

const MOCK_GATEWAY_MESSAGES: Map<GlobalMessageId, NewMessage> = Map::new("gateway_messages");
const MOCK_GATEWAY_MESSAGES: Map<CrossChainUid, NewMessage> = Map::new("gateway_messages");

#[cw_serde]
pub enum MockGatewayExecuteMsg {
Expand All @@ -22,7 +22,7 @@ pub fn mock_gateway_execute(
match msg {
MockGatewayExecuteMsg::RouteMessages(messages) => {
for m in messages {
MOCK_GATEWAY_MESSAGES.save(deps.storage, m.global_id(), &m)?;
MOCK_GATEWAY_MESSAGES.save(deps.storage, m.uid.clone(), &m)?;
}
Ok(Response::new())
}
Expand All @@ -31,7 +31,7 @@ pub fn mock_gateway_execute(

#[cw_serde]
pub enum MockGatewayQueryMsg {
GetMessages { ids: Vec<GlobalMessageId> },
GetMessages { ids: Vec<CrossChainUid> },
}
pub fn mock_gateway_query(deps: Deps, _env: Env, msg: MockGatewayQueryMsg) -> StdResult<Binary> {
let mut msgs = vec![];
Expand All @@ -58,7 +58,7 @@ pub fn get_gateway_messages(
.query_wasm_smart(
gateway_address,
&MockGatewayQueryMsg::GetMessages {
ids: msgs.iter().map(|m| m.global_id()).collect(),
ids: msgs.iter().map(|m| m.uid.clone()).collect(),
},
)
.unwrap()
Expand Down
8 changes: 5 additions & 3 deletions contracts/connection-router/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use connection_router::contract::*;
use connection_router::error::ContractError;
use connection_router::msg::{ExecuteMsg, InstantiateMsg};
use connection_router::state::NewMessage;
use connection_router::types::{ChainName, GatewayDirection};
use connection_router::types::{ChainName, CrossChainUid, GatewayDirection};

pub mod mock;

Expand Down Expand Up @@ -86,10 +86,12 @@ fn generate_messages(
*nonce = *nonce + 1;
let id = format!("tx_id:{}", nonce);
msgs.push(NewMessage {
id_on_chain: id.parse().unwrap(),
uid: CrossChainUid {
id: id.parse().unwrap(),
chain: src_chain.chain_name.clone(),
},
destination_address: "idc".parse().unwrap(),
destination_chain: dest_chain.chain_name.clone(),
source_chain: src_chain.chain_name.clone(),
source_address: "idc".parse().unwrap(),
payload_hash: HexBinary::from(vec![x as u8; 256]),
})
Expand Down

0 comments on commit 9414bcd

Please sign in to comment.