Skip to content

Commit

Permalink
fix: disallow duplicate update header for same height (#709)
Browse files Browse the repository at this point in the history
* fix: prevent update for duplicate height

* chore: pass build

---------

Co-authored-by: sabinchitrakar <[email protected]>
  • Loading branch information
ibrizsabin and sabinchitrakar authored Sep 11, 2023
1 parent b314d0a commit cf365a5
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
42 changes: 42 additions & 0 deletions contracts/cosmwasm-vm/cw-icon-light-client/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,4 +836,46 @@ mod tests {
))
);
}

#[test]
fn test_execute_same_update_client() {
let start_header = &get_test_headers()[0];
let client_id = "test_client".to_string();
let mut deps = init_client(&client_id, start_header, None);

let signed_header: &SignedHeader = &get_test_signed_headers()[1].clone();
let header_any: Any = signed_header.to_any();
let block_height = signed_header.header.clone().unwrap().main_height;
let info = mock_info(SENDER, &[]);
let msg = InstantiateMsg {
ibc_host: Addr::unchecked(SENDER),
};
let _result: Response = instantiate(deps.as_mut(), mock_env(), info.clone(), msg).unwrap();

let msg = ExecuteMsg::UpdateClient {
client_id: client_id.clone(),
signed_header: header_any.encode_to_vec(),
};
let _result = execute(deps.as_mut(), mock_env(), info.clone(), msg.clone()).unwrap();

let updated_client_state =
QueryHandler::get_client_state(deps.as_ref().storage, &client_id).unwrap();

let consensus_state =
QueryHandler::get_consensus_state(deps.as_ref().storage, &client_id, block_height)
.unwrap();

assert_eq!(updated_client_state.latest_height, block_height);

assert_eq!(
consensus_state.message_root,
signed_header.header.clone().unwrap().message_root
);

let second = execute(deps.as_mut(), mock_env(), info, msg);
assert_eq!(
second,
Err(ContractError::HeightAlreadyUpdated { height: 82873 })
);
}
}
3 changes: 3 additions & 0 deletions contracts/cosmwasm-vm/cw-icon-light-client/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ pub enum ContractError {

#[error("UpdateBlockTooOld")]
UpdateBlockTooOld,

#[error("Height {height:?} already updated ")]
HeightAlreadyUpdated { height: u64 },
}

impl From<CwErrors> for ContractError {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,15 @@ impl ILightClient for IconClient<'_> {
) -> Result<ConsensusStateUpdate, Self::Error> {
self.context.ensure_ibc_host(caller)?;
let btp_header = signed_header.header.clone().unwrap();
if self
.context
.get_consensus_state(client_id, btp_header.main_height)
.is_ok()
{
return Err(ContractError::HeightAlreadyUpdated {
height: btp_header.main_height,
});
}

let mut state = self.context.get_client_state(client_id)?;

Expand Down

0 comments on commit cf365a5

Please sign in to comment.