Skip to content

Commit

Permalink
fix: recovery code issue
Browse files Browse the repository at this point in the history
  • Loading branch information
sherpalden committed Nov 7, 2024
1 parent 26e947b commit 311570e
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 14 deletions.
2 changes: 0 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contracts/cosmwasm-vm/cw-cluster-connection/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ cw-xcall-lib = { path="../cw-xcall-lib" }
hex = "0.4.3"
serde-json-wasm = {workspace=true}
sha2 = { version = "0.10.6", default-features = false }
sha3 = { version = "0.10.6", default-features = false }
k256 = "0.11.6"

[dev-dependencies]
Expand Down
5 changes: 1 addition & 4 deletions contracts/cosmwasm-vm/cw-cluster-connection/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
use std::vec;

use common::rlp;
use cosmwasm_std::{coins, Addr, BankMsg, Event, Uint128};
use cw_xcall_lib::network_address::NetId;

Expand Down Expand Up @@ -166,7 +163,7 @@ impl<'a> ClusterConnection<'a> {
let mut msg_vec: Vec<u8> = self.hex_decode(msg)?;

let mut signed_msg = src_network.as_str().as_bytes().to_vec();
signed_msg.append(&mut rlp::encode(&conn_sn).to_vec());
signed_msg.append(&mut to_truncated_le_bytes(conn_sn));
signed_msg.append(&mut msg_vec);

let threshold = self.get_signature_threshold(deps.storage);
Expand Down
33 changes: 29 additions & 4 deletions contracts/cosmwasm-vm/cw-cluster-connection/src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@ pub fn sha256(data: &[u8]) -> Vec<u8> {
sha2::Sha256::digest(&data).to_vec()
}

pub fn keccak256(input: &[u8]) -> [u8; 32] {
use sha3::{Digest, Keccak256};
let mut hasher = Keccak256::new();
hasher.update(input);
let out: [u8; 32] = hasher.finalize().to_vec().try_into().unwrap();
out
}

pub fn to_truncated_le_bytes(n: u128) -> Vec<u8> {
let bytes = n.to_le_bytes();
let trimmed_bytes = bytes
.iter()
.rev()
.skip_while(|&&b| b == 0)
.map(|&b| b)
.collect::<Vec<u8>>();
trimmed_bytes.into_iter().rev().collect()
}

impl<'a> ClusterConnection<'a> {
pub fn ensure_admin(&self, store: &dyn Storage, address: Addr) -> Result<(), ContractError> {
let admin = self.get_admin(store)?;
Expand Down Expand Up @@ -95,22 +114,25 @@ impl<'a> ClusterConnection<'a> {
return Err(ContractError::InsufficientSignatures);
}

let message_hash = sha256(&signed_msg);
let message_hash = keccak256(&signed_msg);

let mut signers: HashMap<String, bool> = HashMap::new();

for signature in signatures {
if signature.len() != 65 {
return Err(ContractError::InvalidSignature);
}
let mut recovery_code = 0;
if signature[0] == 28 {
recovery_code = 1
}
match deps
.api
.secp256k1_recover_pubkey(&message_hash, &signature[0..64], signature[64])
.secp256k1_recover_pubkey(&message_hash, &signature[1..65], recovery_code)
{
Ok(pubkey) => {
let pk = VerifyingKey::from_sec1_bytes(&pubkey)
.map_err(|_| ContractError::InvalidSignature)?;

let pk_hex = hex::encode(pk.to_bytes());
if self.is_validator(deps.storage, pk_hex.clone())
&& !signers.contains_key(&pk_hex)
Expand All @@ -121,7 +143,10 @@ impl<'a> ClusterConnection<'a> {
}
}
}
Err(_) => continue,
Err(e) => {
println!("am i here{:?}", e);
continue;
}
}
}

Expand Down
7 changes: 3 additions & 4 deletions contracts/cosmwasm-vm/cw-cluster-connection/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ pub fn test_recv_message() {
let (mut deps, env, ctx) = instantiate(ADMIN);

let validators =
vec!["02e5e9769497fbc7c7ee57ab39ccedcb612018577d30ca090033dc67ba5d68b8ab".to_string()];
vec!["03e4899bf9b1ef805245f99d28727a592126e9365ddc5c3978a6139b51f9b47f8e".to_string()];
let set_validators_msg = ExecuteMsg::SetValidators {
validators: validators.clone(),
threshold: 1,
Expand All @@ -387,10 +387,9 @@ pub fn test_recv_message() {

// Set up test data
let src_network = NetId::from_str("0x2.icon").unwrap();
let conn_sn: u128 = 5;
let conn_sn: u128 = 456456;
let msg = string_to_hex("hello");
let mut sign_1 = hex::decode("7fe5c14fd4a520417402be8a39405181fca96fb3001e60be8e46623a4430994031e2693ad9eaf71a6bb7ae1bb794afb5561e3f8c3d1248cdd43513a9ab4300b9").unwrap();
sign_1.push(1);
let sign_1 = hex::decode("1c246c2747f0cfe348bd8c33811c881ea26995fc84934ead4d9d875c41c112287b2b17d87fd902cd9b7329dc166f431fc0428c34e36d43153c1104614d7ef35f75").unwrap();
let signatures = vec![sign_1];

// Test with non-relayer sender (should fail)
Expand Down

0 comments on commit 311570e

Please sign in to comment.