-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Revert "revert: aggregate" This reverts commit 00fe615. * test(cw20): cw20 init * test(warp): unit test for cw20 * test(warp): add query test for cw20 * test(warp): remove existing tests for native * feat(warp): add ownable message * wip * test(warp): unit test for native denom * test: use u32 directly * fix!(ism): use parsed u32 merkle index * test: modularize * test: add empty warp * test: runnable mailbox * test: warp placeholder * test: deployable * fix(warp): inject minter to cw20 * fix(warp): use consistant event name * test: warp cw20 / native denom creation * chore: prune * feat: aggregation * schema * fix: evm equivalence * fix(hook): pass entire metadata * fix: aggregate works * chore: remove debugger * fix: tests * clippy * use aggregate ism on integration test * feat: migrate to aggregations (#53)
- Loading branch information
1 parent
f4027eb
commit fbcc641
Showing
54 changed files
with
2,056 additions
and
1,141 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
[package] | ||
name = "hpl-hook-aggregate" | ||
version.workspace = true | ||
authors.workspace = true | ||
edition.workspace = true | ||
license.workspace = true | ||
repository.workspace = true | ||
homepage.workspace = true | ||
documentation.workspace = true | ||
keywords.workspace = true | ||
|
||
[lib] | ||
crate-type = ["cdylib", "rlib"] | ||
|
||
[features] | ||
# for more explicit tests, cargo test --features=backtraces | ||
backtraces = ["cosmwasm-std/backtraces"] | ||
# use library feature to disable all instantiate/execute/query exports | ||
library = [] | ||
|
||
[dependencies] | ||
cosmwasm-std.workspace = true | ||
cosmwasm-storage.workspace = true | ||
cosmwasm-schema.workspace = true | ||
|
||
cw-storage-plus.workspace = true | ||
cw2.workspace = true | ||
cw-utils.workspace = true | ||
|
||
schemars.workspace = true | ||
serde-json-wasm.workspace = true | ||
|
||
thiserror.workspace = true | ||
|
||
hpl-ownable.workspace = true | ||
hpl-interface.workspace = true | ||
|
||
[dev-dependencies] | ||
rstest.workspace = true | ||
ibcx-test-utils.workspace = true | ||
|
||
anyhow.workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use cosmwasm_std::StdError; | ||
|
||
#[derive(thiserror::Error, Debug, PartialEq)] | ||
pub enum ContractError { | ||
#[error("{0}")] | ||
Std(#[from] StdError), | ||
|
||
#[error("{0}")] | ||
PaymentError(#[from] cw_utils::PaymentError), | ||
|
||
#[error("unauthorized")] | ||
Unauthorized {}, | ||
|
||
#[error("hook paused")] | ||
Paused {}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
mod error; | ||
|
||
#[cfg(not(feature = "library"))] | ||
use cosmwasm_std::entry_point; | ||
use cosmwasm_std::{ | ||
ensure_eq, Addr, Coin, CosmosMsg, Deps, DepsMut, Env, Event, HexBinary, MessageInfo, | ||
QueryResponse, Response, StdResult, | ||
}; | ||
use cw_storage_plus::Item; | ||
use error::ContractError; | ||
use hpl_interface::{ | ||
hook::{ | ||
aggregate::{AggregateHookQueryMsg, ExecuteMsg, HooksResponse, InstantiateMsg, QueryMsg}, | ||
post_dispatch, HookQueryMsg, MailboxResponse, PostDispatchMsg, QuoteDispatchMsg, | ||
QuoteDispatchResponse, | ||
}, | ||
to_binary, | ||
types::Message, | ||
}; | ||
use hpl_ownable::get_owner; | ||
|
||
// version info for migration info | ||
pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); | ||
pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); | ||
|
||
pub const HOOKS_KEY: &str = "hooks"; | ||
pub const HOOKS: Item<Vec<Addr>> = Item::new(HOOKS_KEY); | ||
|
||
fn new_event(name: &str) -> Event { | ||
Event::new(format!("hpl_hook_aggregate::{}", name)) | ||
} | ||
|
||
#[cfg_attr(not(feature = "library"), entry_point)] | ||
pub fn instantiate( | ||
deps: DepsMut, | ||
_env: Env, | ||
info: MessageInfo, | ||
msg: InstantiateMsg, | ||
) -> Result<Response, ContractError> { | ||
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; | ||
|
||
let owner = deps.api.addr_validate(&msg.owner)?; | ||
let hooks = msg | ||
.hooks | ||
.iter() | ||
.map(|v| deps.api.addr_validate(v)) | ||
.collect::<StdResult<_>>()?; | ||
|
||
hpl_ownable::initialize(deps.storage, &owner)?; | ||
|
||
HOOKS.save(deps.storage, &hooks)?; | ||
|
||
Ok(Response::new().add_event( | ||
new_event("initialize") | ||
.add_attribute("sender", info.sender) | ||
.add_attribute("owner", owner) | ||
.add_attribute("hooks", msg.hooks.join(",")), | ||
)) | ||
} | ||
|
||
#[cfg_attr(not(feature = "library"), entry_point)] | ||
pub fn execute( | ||
deps: DepsMut, | ||
env: Env, | ||
info: MessageInfo, | ||
msg: ExecuteMsg, | ||
) -> Result<Response, ContractError> { | ||
match msg { | ||
ExecuteMsg::Ownable(msg) => Ok(hpl_ownable::handle(deps, env, info, msg)?), | ||
ExecuteMsg::PostDispatch(PostDispatchMsg { message, metadata }) => { | ||
// aggregate it | ||
let hooks = HOOKS.load(deps.storage)?; | ||
|
||
let msgs: Vec<CosmosMsg> = hooks | ||
.into_iter() | ||
.map(|v| { | ||
let quote = hpl_interface::hook::quote_dispatch( | ||
&deps.querier, | ||
&v, | ||
metadata.clone(), | ||
message.clone(), | ||
)?; | ||
let msg = post_dispatch( | ||
v, | ||
metadata.clone(), | ||
message.clone(), | ||
quote.gas_amount.map(|v| vec![v]), | ||
)? | ||
.into(); | ||
|
||
Ok(msg) | ||
}) | ||
.collect::<StdResult<_>>()?; | ||
|
||
let decoded_msg: Message = message.into(); | ||
|
||
// do nothing | ||
Ok(Response::new().add_messages(msgs).add_event( | ||
new_event("post_dispatch").add_attribute("message_id", decoded_msg.id().to_hex()), | ||
)) | ||
} | ||
ExecuteMsg::SetHooks { hooks } => { | ||
ensure_eq!( | ||
get_owner(deps.storage)?, | ||
info.sender, | ||
ContractError::Unauthorized {} | ||
); | ||
|
||
let parsed_hooks = hooks | ||
.iter() | ||
.map(|v| deps.api.addr_validate(v)) | ||
.collect::<StdResult<_>>()?; | ||
|
||
HOOKS.save(deps.storage, &parsed_hooks)?; | ||
|
||
Ok(Response::new().add_event( | ||
new_event("set_hooks") | ||
.add_attribute("sender", info.sender) | ||
.add_attribute("hooks", hooks.join(",")), | ||
)) | ||
} | ||
} | ||
} | ||
|
||
#[cfg_attr(not(feature = "library"), entry_point)] | ||
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result<QueryResponse, ContractError> { | ||
match msg { | ||
QueryMsg::Ownable(msg) => Ok(hpl_ownable::handle_query(deps, env, msg)?), | ||
QueryMsg::Hook(msg) => match msg { | ||
HookQueryMsg::Mailbox {} => to_binary(get_mailbox(deps)), | ||
HookQueryMsg::QuoteDispatch(QuoteDispatchMsg { metadata, message }) => { | ||
to_binary(quote_dispatch(deps, metadata, message)) | ||
} | ||
}, | ||
QueryMsg::AggregateHook(msg) => match msg { | ||
AggregateHookQueryMsg::Hooks {} => to_binary(get_hooks(deps)), | ||
}, | ||
} | ||
} | ||
|
||
fn get_mailbox(_deps: Deps) -> Result<MailboxResponse, ContractError> { | ||
Ok(MailboxResponse { | ||
mailbox: "unrestricted".to_string(), | ||
}) | ||
} | ||
|
||
fn quote_dispatch( | ||
deps: Deps, | ||
metadata: HexBinary, | ||
message: HexBinary, | ||
) -> Result<QuoteDispatchResponse, ContractError> { | ||
let hooks = HOOKS.load(deps.storage)?; | ||
|
||
let mut total: Option<Coin> = None; | ||
|
||
for hook in hooks { | ||
let res = hpl_interface::hook::quote_dispatch( | ||
&deps.querier, | ||
hook, | ||
metadata.clone(), | ||
message.clone(), | ||
)?; | ||
|
||
if let Some(gas_amount) = res.gas_amount { | ||
total = match total { | ||
Some(mut v) => { | ||
v.amount += gas_amount.amount; | ||
Some(v) | ||
} | ||
None => Some(gas_amount), | ||
}; | ||
} | ||
} | ||
|
||
Ok(QuoteDispatchResponse { gas_amount: total }) | ||
} | ||
|
||
fn get_hooks(deps: Deps) -> Result<HooksResponse, ContractError> { | ||
Ok(HooksResponse { | ||
hooks: HOOKS | ||
.load(deps.storage)? | ||
.into_iter() | ||
.map(|v| v.into()) | ||
.collect(), | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.