Skip to content

Commit

Permalink
Merge pull request #133 from neutron-org/feat/v047-icq
Browse files Browse the repository at this point in the history
ICQ helpers for Cosmos SDK 0.47
  • Loading branch information
pr0n00gler authored Mar 14, 2024
2 parents e493cf8 + d5a055d commit ebdffb3
Show file tree
Hide file tree
Showing 21 changed files with 1,840 additions and 104 deletions.
20 changes: 11 additions & 9 deletions contracts/neutron_interchain_queries/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use cosmwasm_std::{
StdResult, Uint128,
};
use cw2::set_contract_version;
use neutron_sdk::interchain_queries::v045::register_queries::new_register_validators_signing_infos_query_msg;
use neutron_sdk::interchain_queries::v047::register_queries::new_register_validators_signing_infos_query_msg;

use crate::msg::{
Cw20BalanceResponse, ExecuteMsg, GetRecipientTxsResponse, InstantiateMsg, MigrateMsg, QueryMsg,
Expand All @@ -15,20 +15,22 @@ use crate::state::{Transfer, RECIPIENT_TXS, TRANSFERS};
use neutron_sdk::bindings::msg::NeutronMsg;
use neutron_sdk::bindings::query::{NeutronQuery, QueryRegisteredQueryResponse};
use neutron_sdk::bindings::types::{Height, KVKey};
use neutron_sdk::interchain_queries::v045::queries::{
use neutron_sdk::interchain_queries::v047::queries::{
query_balance, query_bank_total, query_delegations, query_distribution_fee_pool,
query_government_proposals, query_staking_validators, query_unbonding_delegations,
query_validators_signing_infos,
};
use neutron_sdk::interchain_queries::{
check_query_type, get_registered_query, query_kv_result,
v045::{
new_register_balance_query_msg, new_register_bank_total_supply_query_msg,
new_register_delegator_delegations_query_msg,
new_register_delegator_unbonding_delegations_query_msg,
new_register_distribution_fee_pool_query_msg, new_register_gov_proposal_query_msg,
new_register_staking_validators_query_msg, new_register_transfers_query_msg,
register_queries::new_register_wasm_contract_store_query_msg,
v047::{
register_queries::{
new_register_balance_query_msg, new_register_bank_total_supply_query_msg,
new_register_delegator_delegations_query_msg,
new_register_delegator_unbonding_delegations_query_msg,
new_register_distribution_fee_pool_query_msg, new_register_gov_proposal_query_msg,
new_register_staking_validators_query_msg, new_register_transfers_query_msg,
new_register_wasm_contract_store_query_msg,
},
types::{COSMOS_SDK_TRANSFER_MSG_URL, RECIPIENT_FIELD},
},
};
Expand Down
68 changes: 33 additions & 35 deletions contracts/neutron_interchain_queries/src/testing/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ use neutron_sdk::interchain_queries::helpers::decode_and_convert;
use neutron_sdk::interchain_queries::types::{
QueryType, TransactionFilterItem, TransactionFilterOp, TransactionFilterValue,
};
use neutron_sdk::interchain_queries::v045::helpers::{
use neutron_sdk::interchain_queries::v047::helpers::{
create_account_denom_balance_key, create_fee_pool_key, create_gov_proposal_key,
create_total_denom_key, create_validator_key,
};
use neutron_sdk::interchain_queries::v045::types::{
use neutron_sdk::interchain_queries::v047::types::{
Balances, FeePool, GovernmentProposal, Proposal, SigningInfo, StakingValidator, TallyResult,
TotalSupply, Validator, ValidatorSigningInfo, RECIPIENT_FIELD,
TotalSupply, Validator, ValidatorSigningInfo, RECIPIENT_FIELD, STAKING_PARAMS_KEY,
};

use neutron_sdk::interchain_queries::v045::queries::{
use neutron_sdk::interchain_queries::v047::queries::{
BalanceResponse, DelegatorDelegationsResponse, FeePoolResponse, ProposalResponse,
TotalSupplyResponse, ValidatorResponse, ValidatorSigningInfoResponse,
};
Expand Down Expand Up @@ -215,14 +215,12 @@ fn build_interchain_query_gov_proposal_value(proposal_id: u64) -> StorageValue {
fn build_interchain_query_balance_response(addr: Addr, denom: String, amount: String) -> Binary {
let converted_addr_bytes = decode_and_convert(addr.as_str()).unwrap();

let balance_key = create_account_denom_balance_key(converted_addr_bytes, &denom).unwrap();

let balance_amount = CosmosCoin { denom, amount };
let balance_key = create_account_denom_balance_key(converted_addr_bytes, denom).unwrap();

let s = StorageValue {
storage_prefix: "".to_string(),
key: Binary(balance_key),
value: Binary(balance_amount.encode_to_vec()),
value: Binary(amount.into_bytes()),
};
Binary::from(
to_string(&QueryRegisteredQueryResultResponse {
Expand Down Expand Up @@ -288,7 +286,7 @@ fn test_query_balance() {
last_submitted_local_height: 987,
balances: Balances {
coins: vec![Coin::new(8278104u128, "uosmo")]
}
},
}
)
}
Expand Down Expand Up @@ -340,9 +338,9 @@ fn test_bank_total_supply_query() {
supply: TotalSupply {
coins: vec![
Coin::new(8278104u128, "uosmo"),
Coin::new(8278104u128, "uatom")
Coin::new(8278104u128, "uatom"),
]
}
},
}
);
}
Expand Down Expand Up @@ -378,7 +376,7 @@ fn test_distribution_fee_pool_query() {
last_submitted_local_height: 987,
pool: FeePool {
coins: vec![Coin::new(8278104u128, "uosmo")]
}
},
}
)
}
Expand Down Expand Up @@ -444,8 +442,8 @@ fn test_gov_proposals_query() {
abstain: "0".to_string(),
yes: "0".to_string(),
no: "0".to_string(),
no_with_veto: "0".to_string()
})
no_with_veto: "0".to_string(),
}),
},
Proposal {
proposal_id: 2,
Expand All @@ -463,8 +461,8 @@ fn test_gov_proposals_query() {
abstain: "0".to_string(),
yes: "0".to_string(),
no: "0".to_string(),
no_with_veto: "0".to_string()
})
no_with_veto: "0".to_string(),
}),
},
Proposal {
proposal_id: 3,
Expand All @@ -482,11 +480,11 @@ fn test_gov_proposals_query() {
abstain: "0".to_string(),
yes: "0".to_string(),
no: "0".to_string(),
no_with_veto: "0".to_string()
})
}
no_with_veto: "0".to_string(),
}),
},
]
}
},
}
)
}
Expand Down Expand Up @@ -578,9 +576,9 @@ fn test_staking_validators_query() {
max_rate: None,
max_change_rate: None,
update_time: None,
}
},
]
}
},
}
)
}
Expand Down Expand Up @@ -646,7 +644,7 @@ fn test_validators_signing_infos_query() {
index_offset: 20,
jailed_until: None,
tombstoned: false,
missed_blocks_counter: 13
missed_blocks_counter: 13,
},
ValidatorSigningInfo {
address: "cosmosvaloper1sjllsnramtg3ewxqwwrwjxfgc4n4ef9u2lcnj0".to_string(),
Expand All @@ -655,9 +653,9 @@ fn test_validators_signing_infos_query() {
jailed_until: Some(1203981203),
tombstoned: false,
missed_blocks_counter: 13,
}
},
]
}
},
}
)
}
Expand All @@ -684,12 +682,12 @@ fn test_query_delegator_delegations() {
// response for `RegisterDelegatorDelegationsQuery` with necessary KV values to test reconstruction logic.
// The values are taken from osmosis network
kv_results: vec![
// params value of staking module for key 'staking/BondDenom'
// value: uosmo
// params value of staking module for key 'staking/params'
// value: Params
StorageValue {
storage_prefix: "params".to_string(),
key: Binary::from(BASE64_STANDARD.decode("c3Rha2luZy9Cb25kRGVub20=").unwrap()),
value: Binary::from(BASE64_STANDARD.decode("InVvc21vIg==").unwrap()),
storage_prefix: "staking".to_string(),
key: Binary::from([STAKING_PARAMS_KEY]),
value: Binary::from(BASE64_STANDARD.decode("CgQIgN9uEGQYByCQTioFdWF0b20yATA6FC0xMDAwMDAwMDAwMDAwMDAwMDAwQhMxMDAwMDAwMDAwMDAwMDAwMDAwShMxMDAwMDAwMDAwMDAwMDAwMDAw").unwrap()),
},
// delegation
// from: osmo1yz54ncxj9csp7un3xled03q6thrrhy9cztkfzs
Expand Down Expand Up @@ -741,7 +739,7 @@ fn test_query_delegator_delegations() {
storage_prefix: "staking".to_string(),
key: Binary::from(decode_hex("2114f8aff987b760a6e4b2b2df48a5a3b7ed2db15006").unwrap()),
value: Binary::from(BASE64_STANDARD.decode("CjJvc21vdmFsb3BlcjFsemhsbnBhaHZ6bndmdjRqbWF5MnRnYWhhNWttejVxeHdtajl3ZRJDCh0vY29zbW9zLmNyeXB0by5lZDI1NTE5LlB1YktleRIiCiBPXCnkQvO+pU6oGbp4ZiJBBZ7RNoLYtXYFOEdpXGH+uSADKg0zMjAxNDM4ODk4NDc2Mh8zMjAxNDM4ODk4NDc2MDAwMDAwMDAwMDAwMDAwMDAwOp8CCgtDaXRhZGVsLm9uZRIQRUJCMDNFQjRCQjRDRkNBNxoTaHR0cHM6Ly9jaXRhZGVsLm9uZSroAUNpdGFkZWwub25lIGlzIGEgbXVsdGktYXNzZXQgbm9uLWN1c3RvZGlhbCBzdGFraW5nIHBsYXRmb3JtIHRoYXQgbGV0cyBhbnlvbmUgYmVjb21lIGEgcGFydCBvZiBkZWNlbnRyYWxpemVkIGluZnJhc3RydWN0dXJlIGFuZCBlYXJuIHBhc3NpdmUgaW5jb21lLiBTdGFrZSB3aXRoIG91ciBub2RlcyBvciBhbnkgb3RoZXIgdmFsaWRhdG9yIGFjcm9zcyBtdWx0aXBsZSBuZXR3b3JrcyBpbiBhIGZldyBjbGlja3NKAFJECjoKETUwMDAwMDAwMDAwMDAwMDAwEhIyMDAwMDAwMDAwMDAwMDAwMDAaETMwMDAwMDAwMDAwMDAwMDAwEgYIkKKzhgZaATE=").unwrap()),
}
},
],
height: 0,
revision: 0,
Expand All @@ -767,18 +765,18 @@ fn test_query_delegator_delegations() {
Delegation {
delegator: Addr::unchecked("osmo1yz54ncxj9csp7un3xled03q6thrrhy9cztkfzs"),
validator: "osmovaloper1r2u5q6t6w0wssrk6l66n3t2q3dw2uqny4gj2e3".to_string(),
amount: Coin::new(5177628u128, "uosmo".to_string())
amount: Coin::new(5177628u128, "uatom".to_string()),
},
Delegation {
delegator: Addr::unchecked("osmo1yz54ncxj9csp7un3xled03q6thrrhy9cztkfzs"),
validator: "osmovaloper1ej2es5fjztqjcd4pwa0zyvaevtjd2y5w37wr9t".to_string(),
amount: Coin::new(29620221u128, "uosmo".to_string())
amount: Coin::new(29620221u128, "uatom".to_string()),
},
Delegation {
delegator: Addr::unchecked("osmo1yz54ncxj9csp7un3xled03q6thrrhy9cztkfzs"),
validator: "osmovaloper1lzhlnpahvznwfv4jmay2tgaha5kmz5qxwmj9we".to_string(),
amount: Coin::new(219920u128, "uosmo".to_string())
}
amount: Coin::new(219920u128, "uatom".to_string()),
},
],
}
)
Expand Down
15 changes: 7 additions & 8 deletions contracts/neutron_interchain_txs/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ use neutron_sdk::{
query::{NeutronQuery, QueryInterchainAccountAddressResponse},
types::ProtobufAny,
},
interchain_txs::helpers::{
decode_acknowledgement_response, decode_message_response, get_port_id,
},
interchain_txs::helpers::{decode_message_response, get_port_id},
interchain_txs::v047::helpers::decode_acknowledgement_response,
query::min_ibc_fee::query_min_ibc_fee,
sudo::msg::{RequestPacket, SudoMsg},
NeutronError, NeutronResult,
Expand Down Expand Up @@ -242,7 +241,7 @@ fn execute_delegate(
}

let any_msg = ProtobufAny {
type_url: "/cosmos.staking.v1beta1.MsgDelegate".to_string(),
type_url: "/cosmos.staking.v1beta1.MsgDelegateResponse".to_string(),
value: Binary::from(buf),
};

Expand Down Expand Up @@ -450,7 +449,7 @@ fn sudo_response(deps: DepsMut, request: RequestPacket, data: Binary) -> StdResu

let mut item_types = vec![];
for item in parsed_data {
let item_type = item.msg_type.as_str();
let item_type = item.type_url.as_str();
item_types.push(item_type.to_string());
match item_type {
"/cosmos.staking.v1beta1.MsgUndelegate" => {
Expand All @@ -459,7 +458,7 @@ fn sudo_response(deps: DepsMut, request: RequestPacket, data: Binary) -> StdResu
// FOR LATER INSPECTION.
// In this particular case, a mismatch between the string message type and the
// serialised data layout looks like a fatal error that has to be investigated.
let out: MsgUndelegateResponse = decode_message_response(&item.data)?;
let out: MsgUndelegateResponse = decode_message_response(&item.value)?;

// NOTE: NO ERROR IS RETURNED HERE. THE CHANNEL LIVES ON.
// In this particular case, we demonstrate that minor errors should not
Expand All @@ -474,13 +473,13 @@ fn sudo_response(deps: DepsMut, request: RequestPacket, data: Binary) -> StdResu
deps.api
.debug(format!("Undelegation completion time: {:?}", completion_time).as_str());
}
"/cosmos.staking.v1beta1.MsgDelegate" => {
"/cosmos.staking.v1beta1.MsgDelegateResponse" => {
// WARNING: RETURNING THIS ERROR CLOSES THE CHANNEL.
// AN ALTERNATIVE IS TO MAINTAIN AN ERRORS QUEUE AND PUT THE FAILED REQUEST THERE
// FOR LATER INSPECTION.
// In this particular case, a mismatch between the string message type and the
// serialised data layout looks like a fatal error that has to be investigated.
let _out: MsgDelegateResponse = decode_message_response(&item.data)?;
let _out: MsgDelegateResponse = decode_message_response(&item.value)?;
}
_ => {
deps.api.debug(
Expand Down
8 changes: 7 additions & 1 deletion packages/neutron-sdk/src/errors/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ pub enum NeutronError {
#[error("{0}")]
Fmt(#[from] std::fmt::Error),

#[error("{0}")]
FromUTF8Error(#[from] std::string::FromUtf8Error),

#[error("Bech32 error")]
Bech32(#[from] bech32::Error),

#[error("Prost protobuf error")]
ProstProtobuf(#[from] cosmos_sdk_proto::prost::DecodeError),
ProstProtobuf(#[from] prost::DecodeError),

#[error("Serde JSON (Wasm) error")]
SerdeJSONWasm(String),
Expand Down Expand Up @@ -47,6 +50,9 @@ pub enum NeutronError {

#[error("Too many transaction filters, max allowed: {max:?}")]
TooManyTransactionFilters { max: usize },

#[error("Can't deconstruct account denom balance key: {0}")]
AccountDenomBalanceKeyDeconstructionError(String),
}

impl From<serde_json_wasm::de::Error> for NeutronError {
Expand Down
8 changes: 8 additions & 0 deletions packages/neutron-sdk/src/interchain_queries/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::errors::error::{NeutronError, NeutronResult};
use crate::interchain_queries::types::{AddressBytes, MAX_ADDR_LEN};
use cosmwasm_std::{StdError, Uint128, Uint256};

/// Decodes a bech32 encoded string and converts to base64 encoded bytes
/// </~https://github.com/cosmos/cosmos-sdk/blob/ad9e5620fb3445c716e9de45cfcdb56e8f1745bf/types/bech32/bech32.go#L20>
Expand Down Expand Up @@ -29,3 +30,10 @@ pub fn length_prefix<AddrBytes: AsRef<[u8]>>(addr: AddrBytes) -> NeutronResult<V

Ok(p)
}

pub fn uint256_to_u128(value: Uint256) -> Result<u128, StdError> {
let converted: Uint128 = value
.try_into()
.map_err(|_| StdError::generic_err("Uint256 value exceeds u128 limits"))?;
Ok(converted.u128())
}
1 change: 1 addition & 0 deletions packages/neutron-sdk/src/interchain_queries/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ pub mod helpers;
pub mod queries;
pub mod types;
pub mod v045;
pub mod v047;

pub use queries::{check_query_type, get_registered_query, query_kv_result};
11 changes: 11 additions & 0 deletions packages/neutron-sdk/src/interchain_queries/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
bindings::types::{KVKey, StorageValue},
errors::error::NeutronResult,
};
use cosmwasm_std::{from_json, StdError, Uint128};
use schemars::{JsonSchema, _serde_json::Value};
use serde::{Deserialize, Deserializer, Serialize, Serializer};

Expand Down Expand Up @@ -122,3 +123,13 @@ pub trait KVReconstruct: Sized {
/// Reconstructs this value from the slice of **StorageValue**'s.
fn reconstruct(kvs: &[StorageValue]) -> NeutronResult<Self>;
}

impl KVReconstruct for Uint128 {
fn reconstruct(storage_values: &[StorageValue]) -> NeutronResult<Uint128> {
let value = storage_values
.first()
.ok_or_else(|| StdError::generic_err("empty query result"))?;
let balance: Uint128 = from_json(&value.value)?;
Ok(balance)
}
}
Loading

0 comments on commit ebdffb3

Please sign in to comment.