Skip to content

Commit

Permalink
feat(v3): hyperlane core implementation (#45)
Browse files Browse the repository at this point in the history
* cleanup hooks

* remove "Owned"

* organize interfaec

* generic router

* router -> route

* support custom query

* one file contract

* avoid duplication

* ownable

* pausable

* useful kids

* rename methods

* apply to routing-hook

* cleanup

* define hook interface

* typo

* warp: fix error temp

* feat: add conn

* feat: deprecate hub

* hook: typo

* igp: cleanup

* new ism types

* rename event & method

* deprecate hub

* feat: add package prefix

* feat: add package prefix (2)

* test: ownable

* test: pausable

* fix(ownable): use Ownable class as possible

* feat: add pausable alias into workspace

* feat: add `wrap` method to easy to call

* fix: remove `Binary` usage

* feat: v3 mailbox

* fix(mailbox): use contract_querier

* fix(va): compile error

* fix!(va): not to use Binary

* fix!: not to use `Binary`

* refactor(va): merge tests

* chore(mailbox): make public & prune imports

* fix(va): use 'hrp'

* feat: gen schema in build time

* chore(router): move test

* chore(va): redundant

* chore: use event_to_resp

* fix(router): remove Default

* feat: share `to_binary`

* feat: wrap method for `QuoteDispatchMsg`

* fix: export message directly

* feat(hook): implement routing hook

* feat(hook): add schema build script

* feat(hook): add mailbox

* feat(hook): apply mailbox rbac

* fix(ownable): use ensure

* feat(hook): implement all

* remove migrate msg

* fix(hook): revive quote dispatch

* fix(hook): apply quote dispatch msg

* fix: suggestions

* feat: igp interface helper

* feat(igp): schema builder

* feat(igp): v3 igp-core - wip (1)

* chore(hook): visibility

* feat(hook): custom, fallback routing hook

* feat(hook): custom, fallback routing hook interface

* feat(igp): wip - 2

* refactor(igp): simplify package name

* fix(igp): no compile error

* fix(igp): broken

* feat(ism): multisig - wip 1

* fix(igp): oracle test

* chore: pausable test

* fix(ism): routing test

* refactor(warp): cleanup interface

* feat(warp): wip 2

* feat(warp): native

* feat(warp): generic token option

* feat(warp): cw20

* fix: buildable

* test(core): mailbox

* fix: duplicated

* fix(schema): all in one

* chore: schema command

* test(core): mailbox - 2

* test(core): va - 1

* feat: move crypto things to types

* deps: correct package alias

* fix!: remove `untagged`

* test(core): va - done

* fix!: untagged sideeffects

* feat(core): add required hook

* feat(core): query required hook

* fix(router): check owner

* test(hook): merkle

* test(hook): pausable

* feat(hook): default paused field

* chore(hook): derive Default

* test: overflow

* test: redundant fmt

* fix(warp): clippy suggestions

* test(warp): native - 1

* test(core): required hook

* test(hook): routing

* feat!!!: bump v0.0.2

* test: schema tester

* test(hook): add default test

* test(hook): using macro

* fix(mock): using gas_token

* feat(igp): add dest_domain field

* test(hook): routing custom hook

* feat(igp): add mailbox

* chore: build-dev before check

* chore: clean

* test(igp): rstest

* test(igp): add features

* test(igp): add get beneficiary

* feat: verisoning

* feat!(ism): unify interface

* ism schema

* fix!: mailbox query

* fix: add get_nonce function to mailbox contract (#46)

* feat: add get_nonce function to mailbox

* remove bind

---------

Co-authored-by: byeongsu-hong <[email protected]>

* test(core): add init test

* test(core): remove 'revised'

* docs: add deploy sequence

* test: add test executor

* fix(core): typo

* test(mock): use expected interface

* test: update contract list

* test(mock): use uosmo denom

* fix(core): check insufficient amount

* fix(core): dispatch / process

* chore: local dependency

* feat(ism): add expected ism query msg

* fix(ism): convention

* feat(core): add quote gas query

* fix(e2e): wip

* fix(warp): correct comment

Co-authored-by: Yorke Rhodes <[email protected]>

* fix(core): hook metadata feature

* feat(hook): add aggregate - wip

* feat(ism): aggregate ism

* feat: aggregate for ism

* test(warp): fixed tests

* pnpm install

* feat: deploy scripts - wip

* fix(core): gas policy - peer review needed

* fix(core): clippy

* feat(hook): aggregate - wip

* feat: deployer

* feat(hook): add index field

* test: add schema test for mock contract

* feat: warp deployer

* test(hook): assert event attribute

* test: fixtures

* test(e2e): fix deployer

* fix(hook): separate event

* fix(hook): revive attr

* fix: cw e2e deployer

* token warp deployer and linker

* feat: wip script

* fix(core): code review

* fix: verify income message with latest dispatched id

* feat: public pausable hook

* fix(hook): make routing hooks public

* fix(ism): use message id multisig

* v0.0.6-rc1

* fix: duplicated owner assertion

* chore: polishing

* feat: apply new metadata structure

* fix(hook): use prev index

* fix(ism): new metadata

* test: working?

* fix: working

* chore: remove redundant debug

* fix: correct query

* revert: aggregate

* fix: metadata - wip

* test: disable unit tests for warp route

* chore: clippy

---------

Co-authored-by: Eric <[email protected]>
Co-authored-by: Yorke Rhodes <[email protected]>
  • Loading branch information
3 people committed Oct 20, 2023
1 parent 1a241a4 commit a259002
Show file tree
Hide file tree
Showing 25 changed files with 1,116 additions and 845 deletions.
3 changes: 2 additions & 1 deletion contracts/hooks/aggregate/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "hpl-hook-aggregate"
name = "hpl-hook-routing"
version.workspace = true
authors.workspace = true
edition.workspace = true
Expand Down Expand Up @@ -33,6 +33,7 @@ serde-json-wasm.workspace = true
thiserror.workspace = true

hpl-ownable.workspace = true
hpl-router.workspace = true
hpl-interface.workspace = true

[dev-dependencies]
Expand Down
4 changes: 1 addition & 3 deletions contracts/hooks/merkle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,6 @@ mod test {
#[rstest]
#[case("mailbox", None)]
#[should_panic(expected = "unauthorized")]
#[case("owner", None)]
#[should_panic(expected = "unauthorized")]
#[case("mailbox", Some(hex(TEST_MESSAGE_FAIL)))]
fn test_post_dispatch(
mut deps: TestDeps,
Expand Down Expand Up @@ -307,7 +305,7 @@ mod test {

let tree = MESSAGE_TREE.load(deps.as_ref().storage).unwrap();
assert_ne!(tree, MerkleTree::default());
assert_eq!(tree.count, 0);
assert_eq!(tree.count, 1);
}

#[rstest]
Expand Down
9 changes: 2 additions & 7 deletions contracts/igps/core/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use cosmwasm_std::{Coin, Uint256};

#[derive(thiserror::Error, Debug, PartialEq)]
pub enum ContractError {
#[error("{0}")]
Expand All @@ -14,11 +12,8 @@ pub enum ContractError {
#[error("unauthorized")]
Unauthorized {},

#[error("insufficient funds: needed {gas_needed:?}, but only received {received:?}")]
InsufficientFunds {
received: Uint256,
gas_needed: Uint256,
},
#[error("insufficient funds")]
InsufficientFunds {},

#[error("gas oracle not found for {0}")]
GasOracleNotFound(u32),
Expand Down
8 changes: 1 addition & 7 deletions contracts/igps/core/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,7 @@ pub fn pay_for_gas(
let gas_token = GAS_TOKEN.load(deps.storage)?;
let received = Uint256::from(cw_utils::must_pay(&info, &gas_token)?);
let gas_needed = quote_gas_price(deps.storage, &deps.querier, dest_domain, gas_amount)?;
ensure!(
received >= gas_needed,
ContractError::InsufficientFunds {
received,
gas_needed,
}
);
ensure!(received >= gas_needed, ContractError::InsufficientFunds {});

let payment_gap = Uint128::from_str(&(received - gas_needed).to_string())?;

Expand Down
19 changes: 15 additions & 4 deletions contracts/igps/core/src/tests/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ fn test_mock_querier(v: &WasmQuery) -> QuerierResult {

match *split.first().unwrap() {
"oracle" => match msg {
oracle::IgpGasOracleQueryMsg::GetExchangeRateAndGasPrice { .. } => {
oracle::QueryMsg::Oracle(
oracle::IgpGasOracleQueryMsg::GetExchangeRateAndGasPrice { .. },
) => {
let gas_price = split.pop().unwrap().parse::<u128>().unwrap();
let exchange_rate = split.pop().unwrap().parse::<u128>().unwrap();

Expand All @@ -42,6 +44,7 @@ fn test_mock_querier(v: &WasmQuery) -> QuerierResult {

SystemResult::Ok(ContractResult::Ok(res))
}
_ => unreachable!("unsupported query"),
},
_ => unreachable!("unsupported query"),
}
Expand Down Expand Up @@ -131,7 +134,9 @@ fn test_set_gas_oracles(mut igp: IGP, #[case] sender: Addr) {
fn test_set_beneficiary(mut igp: IGP, #[case] sender: Addr) {
let next_beneficiary = Addr::unchecked("next-beneficiary");

igp.set_beneficiary(&sender, &next_beneficiary).unwrap();
igp.set_beneficiary(&sender, &next_beneficiary)
.map_err(|e| e.to_string())
.unwrap();

let storage = igp.deps_ref().storage;
let actual_beneficiary = BENEFICIARY.load(storage).unwrap();
Expand Down Expand Up @@ -160,7 +165,10 @@ fn test_get_quote_gas_payment(

igp.deps.querier.update_wasm(test_mock_querier);

let resp = igp.get_quote_gas_payment(dest_domain, gas_amount).unwrap();
let resp = igp
.get_quote_gas_payment(dest_domain, gas_amount)
.map_err(|e| e.to_string())
.unwrap();
assert_eq!(resp.gas_needed, Uint256::from_u128(9 * 10u128.pow(15)))
}

Expand All @@ -176,7 +184,10 @@ fn test_gas_exchange(

igp.deps.querier.update_wasm(test_mock_querier);

let resp = igp.get_exchange_rate_and_gas_price(dest_domain).unwrap();
let resp = igp
.get_exchange_rate_and_gas_price(dest_domain)
.map_err(|e| e.to_string())
.unwrap();
assert_eq!(resp.gas_price, Uint128::new(150 * DEC_9));
assert_eq!(resp.exchange_rate, Uint128::new(2 * DEC_9));
}
Expand Down
13 changes: 6 additions & 7 deletions contracts/isms/aggregate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,21 @@ library = []
[dependencies]
cosmwasm-std.workspace = true
cosmwasm-storage.workspace = true
cosmwasm-schema.workspace = true

cw-storage-plus.workspace = true
cw2.workspace = true

sha2.workspace = true
ripemd.workspace = true

bech32.workspace = true
schemars.workspace = true
sha3.workspace = true

schemars.workspace = true
serde.workspace = true
thiserror.workspace = true
cosmwasm-schema.workspace = true

hpl-ownable.workspace = true
hpl-interface.workspace = true

[dev-dependencies]
rstest.workspace = true

serde.workspace = true
anyhow.workspace = true
8 changes: 0 additions & 8 deletions contracts/isms/aggregate/src/lib.rs

This file was deleted.

12 changes: 12 additions & 0 deletions contracts/isms/multisig/src/execute/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ mod test {

mock_owner(deps.as_mut().storage, owner.clone());

HRP.save(deps.as_mut().storage, &"data".to_string())
.unwrap();

let msg = MsgValidatorSet {
domain: 1u32,
validator: "test".to_string(),
Expand Down Expand Up @@ -235,6 +238,9 @@ mod test {
let validator: String = VALIDATOR_ADDR.to_string();
let domain: u32 = 1;

HRP.save(deps.as_mut().storage, &"data".to_string())
.unwrap();

mock_owner(deps.as_mut().storage, owner.clone());
let msg = MsgValidatorSet {
domain,
Expand Down Expand Up @@ -285,6 +291,9 @@ mod test {

mock_owner(deps.as_mut().storage, owner);

HRP.save(deps.as_mut().storage, &"data".to_string())
.unwrap();

let msg = vec![
MsgValidatorSet {
domain: 1u32,
Expand Down Expand Up @@ -315,6 +324,9 @@ mod test {
let validator_pubkey = HexBinary::from_hex(VALIDATOR_PUBKEY).unwrap();
mock_owner(deps.as_mut().storage, owner.clone());

HRP.save(deps.as_mut().storage, &"data".to_string())
.unwrap();

let msg = vec![
MsgValidatorSet {
domain: 1u32,
Expand Down
4 changes: 2 additions & 2 deletions contracts/isms/multisig/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ pub fn eth_hash(message: HexBinary) -> Result<HexBinary, ContractError> {
pub fn multisig_hash(
mut domain_hash: Vec<u8>,
mut root: Vec<u8>,
index: u32,
mut index: Vec<u8>,
mut message_id: Vec<u8>,
) -> Result<HexBinary, ContractError> {
let mut bz = vec![];

bz.append(&mut domain_hash);
bz.append(&mut root);
bz.append(&mut index.to_be_bytes().to_vec());
bz.append(&mut index);
bz.append(&mut message_id);

let hash = keccak256_hash(&bz);
Expand Down
2 changes: 1 addition & 1 deletion contracts/isms/multisig/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub fn verify_message(
let multisig_hash = multisig_hash(
domain_hash(message.origin_domain, metadata.origin_merkle_tree)?.to_vec(),
metadata.merkle_root.to_vec(),
0,
metadata.merkle_index.to_vec(),
message.id().to_vec(),
)?;

Expand Down
Loading

0 comments on commit a259002

Please sign in to comment.