Skip to content

Commit

Permalink
Merge branch 'main' into multisig-ed25519
Browse files Browse the repository at this point in the history
  • Loading branch information
eranrund authored Sep 22, 2023
2 parents 8f3df86 + ff60415 commit b0bec37
Showing 1 changed file with 129 additions and 7 deletions.
136 changes: 129 additions & 7 deletions contracts/multisig-prover/src/encoding/bcs.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,50 @@
use bcs::to_bytes;
use cosmwasm_std::{HexBinary, Uint256};
use itertools::Itertools;
use multisig::{key::Signature, msg::Signer};

use crate::error::ContractError;
use crate::{error::ContractError, types::Operator};

use super::Data;

// TODO: all of the public functions in this file should be moved to a trait,
// that has an abi and bcs implementation (and possibly others)

#[allow(dead_code)]
fn encode_proof(
quorum: Uint256,
signers: Vec<(Signer, Option<Signature>)>,
) -> Result<HexBinary, ContractError> {
let mut operators = make_operators_with_sigs(signers);
operators.sort(); // gateway requires operators to be sorted

let (addresses, weights, signatures): (Vec<_>, Vec<_>, Vec<_>) = operators
.iter()
.map(|op| {
(
op.address.to_vec(),
u256_to_u128(op.weight),
op.signature.as_ref().map(|sig| sig.as_ref().to_vec()),
)
})
.multiunzip();

let signatures: Vec<Vec<u8>> = signatures.into_iter().flatten().collect();
let quorum = u256_to_u128(quorum);
Ok(to_bytes(&(addresses, weights, quorum, signatures))?.into())
}

fn make_operators_with_sigs(signers_with_sigs: Vec<(Signer, Option<Signature>)>) -> Vec<Operator> {
signers_with_sigs
.into_iter()
.map(|(signer, sig)| Operator {
address: signer.pub_key.into(),
weight: signer.weight,
signature: sig,
})
.collect()
}

pub fn command_params(
source_chain: String,
source_address: String,
Expand Down Expand Up @@ -41,10 +77,6 @@ pub fn command_params(
.into())
}

fn u256_to_u64(chain_id: Uint256) -> u64 {
chain_id.to_string().parse().expect("chain_id is invalid")
}

fn make_command_id(command_id: &HexBinary) -> [u8; 32] {
// command-ids are fixed length sequences
command_id
Expand Down Expand Up @@ -79,28 +111,118 @@ pub fn encode(data: &Data) -> HexBinary {
.into()
}

fn u256_to_u128(val: Uint256) -> u128 {
val.to_string().parse().expect("value is larger than u128")
}

fn u256_to_u64(chain_id: Uint256) -> u64 {
chain_id
.to_string()
.parse()
.expect("value is larger than u64")
}

#[cfg(test)]
mod test {

use std::vec;

use bcs::from_bytes;
use cosmwasm_std::{HexBinary, Uint256};
use cosmwasm_std::{Addr, HexBinary, Uint256};
use multisig::{
key::{PublicKey, Signature},
msg::Signer,
};

use crate::{
encoding::{
bcs::{command_params, encode, make_command_id, u256_to_u64},
bcs::{
command_params, encode, encode_proof, make_command_id, u256_to_u128, u256_to_u64,
},
Data,
},
types::Command,
};

#[test]
fn test_u256_to_u128() {
let val = u128::MAX;
assert_eq!(val, u256_to_u128(Uint256::from(val)));
}

#[test]
fn test_chain_id_as_u64() {
let chain_id = 1u64;
assert_eq!(chain_id, u256_to_u64(Uint256::from(chain_id as u128)));
}

#[test]
#[should_panic]
fn test_u256_to_u128_fails() {
let _ = u256_to_u128(Uint256::MAX);
}

#[test]
fn test_encode_proof() {
let signers = vec![
(Signer {
address: Addr::unchecked("axelarvaloper1ff675m593vve8yh82lzhdnqfpu7m23cxstr6h4"),
weight: Uint256::from(10u128),
pub_key: PublicKey::Ecdsa(
HexBinary::from_hex(
"03c6ddb0fcee7b528da1ef3c9eed8d51eeacd7cc28a8baa25c33037c5562faa6e4",
)
.unwrap(),
),
},
Some(Signature::Ecdsa(
HexBinary::from_hex("283786d844a7c4d1d424837074d0c8ec71becdcba4dd42b5307cb543a0e2c8b81c10ad541defd5ce84d2a608fc454827d0b65b4865c8192a2ea1736a5c4b72021b").unwrap()))),
(Signer {
address: Addr::unchecked("axelarvaloper1x86a8prx97ekkqej2x636utrdu23y8wupp9gk5"),
weight: Uint256::from(10u128),
pub_key: PublicKey::Ecdsa(
HexBinary::from_hex(
"03d123ce370b163acd576be0e32e436bb7e63262769881d35fa3573943bf6c6f81",
)
.unwrap(),
),
},
Some(Signature::Ecdsa(
HexBinary::from_hex("283786d844a7c4d1d424837074d0c8ec71becdcba4dd42b5307cb543a0e2c8b81c10ad541defd5ce84d2a608fc454827d0b65b4865c8192a2ea1736a5c4b72021b").unwrap())))];

let quorum = Uint256::from(10u128);
let proof = encode_proof(quorum, signers.clone());

assert!(proof.is_ok());
let proof = proof.unwrap();
let decoded_proof: Result<(Vec<Vec<u8>>, Vec<u128>, u128, Vec<Vec<u8>>), _> =
from_bytes(&proof);
assert!(decoded_proof.is_ok());
let (operators, weights, quorum_decoded, signatures): (
Vec<Vec<u8>>,
Vec<u128>,
u128,
Vec<Vec<u8>>,
) = decoded_proof.unwrap();

assert_eq!(operators.len(), signers.len());
assert_eq!(weights.len(), signers.len());
assert_eq!(signatures.len(), signers.len());
assert_eq!(quorum_decoded, 10u128);

for i in 0..signers.len() {
assert_eq!(
operators[i],
HexBinary::from(signers[i].0.pub_key.clone()).to_vec()
);
assert_eq!(weights[i], 10u128);
assert_eq!(
signatures[i],
HexBinary::from(signers[i].1.clone().unwrap()).to_vec()
);
}
}

#[test]
#[should_panic]
fn test_chain_id_as_u64_fails() {
Expand Down

0 comments on commit b0bec37

Please sign in to comment.