Skip to content

Commit 6b07ae6

Browse files
jayantkJayant Krishnamurthy
andauthored
Add query methods to cosmwasm contract (#441)
* implement query operations * more governance * revert * update the terra sdk? * wtf * fix ci * add tests Co-authored-by: Jayant Krishnamurthy <[email protected]>
1 parent bddcb69 commit 6b07ae6

File tree

4 files changed

+129
-18
lines changed

4 files changed

+129
-18
lines changed

cosmwasm/contracts/pyth/src/contract.rs

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use {
2323
},
2424
},
2525
cosmwasm_std::{
26+
coin,
2627
entry_point,
2728
has_coins,
2829
to_binary,
@@ -32,6 +33,8 @@ use {
3233
DepsMut,
3334
Env,
3435
MessageInfo,
36+
OverflowError,
37+
OverflowOperation,
3538
QueryRequest,
3639
Response,
3740
StdResult,
@@ -365,9 +368,8 @@ fn update_price_feed_if_new(
365368
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
366369
match msg {
367370
QueryMsg::PriceFeed { id } => to_binary(&query_price_feed(deps, env, id.as_ref())?),
368-
// TODO: implement queries for the update fee and valid time period along the following lines:
369-
// QueryMsg::GetUpdateFee { data: bytes[] } => ???,
370-
// QueryMsg::GetValidTimePeriod => ???
371+
QueryMsg::GetUpdateFee { vaas } => to_binary(&get_update_fee(deps, &vaas)?),
372+
QueryMsg::GetValidTimePeriod => to_binary(&get_valid_time_period(deps)?),
371373
}
372374
}
373375

@@ -403,6 +405,26 @@ pub fn query_price_feed(deps: Deps, env: Env, address: &[u8]) -> StdResult<Price
403405
}
404406
}
405407

408+
pub fn get_update_fee(deps: Deps, vaas: &[Binary]) -> StdResult<Coin> {
409+
let config = config_read(deps.storage).load()?;
410+
Ok(coin(
411+
config
412+
.fee
413+
.u128()
414+
.checked_mul(vaas.len() as u128)
415+
.ok_or(OverflowError::new(
416+
OverflowOperation::Mul,
417+
config.fee,
418+
vaas.len(),
419+
))?,
420+
config.fee_denom,
421+
))
422+
}
423+
424+
pub fn get_valid_time_period(deps: Deps) -> StdResult<Duration> {
425+
Ok(config_read(deps.storage).load()?.valid_time_period)
426+
}
427+
406428
#[cfg(test)]
407429
mod test {
408430
use {
@@ -846,6 +868,65 @@ mod test {
846868
);
847869
}
848870

871+
#[test]
872+
fn test_get_update_fee() {
873+
let (mut deps, _env) = setup_test();
874+
let fee_denom: String = "test".into();
875+
config(&mut deps.storage)
876+
.save(&ConfigInfo {
877+
fee: Uint128::new(10),
878+
fee_denom: fee_denom.clone(),
879+
..create_zero_config_info()
880+
})
881+
.unwrap();
882+
883+
let updates = vec![Binary::from([1u8]), Binary::from([2u8])];
884+
885+
assert_eq!(
886+
get_update_fee(deps.as_ref(), &updates[0..0]),
887+
Ok(Coin::new(0, fee_denom.clone()))
888+
);
889+
assert_eq!(
890+
get_update_fee(deps.as_ref(), &updates[0..1]),
891+
Ok(Coin::new(10, fee_denom.clone()))
892+
);
893+
assert_eq!(
894+
get_update_fee(deps.as_ref(), &updates[0..2]),
895+
Ok(Coin::new(20, fee_denom.clone()))
896+
);
897+
898+
let big_fee: Uint128 = Uint128::from((u128::MAX / 4) * 3);
899+
config(&mut deps.storage)
900+
.save(&ConfigInfo {
901+
fee: big_fee,
902+
fee_denom: fee_denom.clone(),
903+
..create_zero_config_info()
904+
})
905+
.unwrap();
906+
907+
assert_eq!(
908+
get_update_fee(deps.as_ref(), &updates[0..1]),
909+
Ok(Coin::new(big_fee.u128(), fee_denom))
910+
);
911+
assert!(get_update_fee(deps.as_ref(), &updates[0..2]).is_err());
912+
}
913+
914+
#[test]
915+
fn test_get_valid_time_period() {
916+
let (mut deps, _env) = setup_test();
917+
config(&mut deps.storage)
918+
.save(&ConfigInfo {
919+
valid_time_period: Duration::from_secs(10),
920+
..create_zero_config_info()
921+
})
922+
.unwrap();
923+
924+
assert_eq!(
925+
get_valid_time_period(deps.as_ref()),
926+
Ok(Duration::from_secs(10))
927+
);
928+
}
929+
849930
#[test]
850931
fn test_add_data_source_ok_with_owner() {
851932
let (mut deps, env) = setup_test();

cosmwasm/contracts/pyth/src/msg.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ use {
44
Binary,
55
Uint128,
66
},
7+
pyth_sdk_cw::{
8+
PriceFeed,
9+
PriceIdentifier,
10+
},
711
schemars::JsonSchema,
812
serde::{
913
Deserialize,
@@ -14,6 +18,7 @@ use {
1418
type HumanAddr = String;
1519

1620
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
21+
#[serde(rename_all = "snake_case")]
1722
pub struct InstantiateMsg {
1823
pub wormhole_contract: HumanAddr,
1924
// TODO: this should support multiple emitters
@@ -43,7 +48,17 @@ pub enum ExecuteMsg {
4348
#[serde(rename_all = "snake_case")]
4449
pub struct MigrateMsg {}
4550

46-
pub use pyth_sdk_cw::{
47-
PriceFeedResponse,
48-
QueryMsg,
49-
};
51+
52+
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
53+
#[serde(rename_all = "snake_case")]
54+
pub enum QueryMsg {
55+
PriceFeed { id: PriceIdentifier },
56+
GetUpdateFee { vaas: Vec<Binary> },
57+
GetValidTimePeriod,
58+
}
59+
60+
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
61+
#[serde(rename_all = "snake_case")]
62+
pub struct PriceFeedResponse {
63+
pub price_feed: PriceFeed,
64+
}

third_party/pyth/p2w-relay/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

third_party/pyth/p2w-relay/src/relay/terra.ts

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import { fromUint8Array } from "js-base64";
21
import {
32
Coin,
43
LCDClient,
54
LCDClientConfig,
65
MnemonicKey,
76
MsgExecuteContract,
87
} from "@terra-money/terra.js";
9-
import { hexToUint8Array } from "@certusone/wormhole-sdk";
108
import axios from "axios";
119
import { logger } from "../helpers";
1210

@@ -66,6 +64,9 @@ export class TerraRelay implements Relay {
6664

6765
const wallet = lcdClient.wallet(mk);
6866

67+
logger.debug("TIME: Querying fee");
68+
let fee: Coin = await this.getUpdateFee(signedVAAs);
69+
6970
logger.debug("TIME: creating messages");
7071
let msgs = new Array<MsgExecuteContract>();
7172
for (let idx = 0; idx < signedVAAs.length; ++idx) {
@@ -77,8 +78,7 @@ export class TerraRelay implements Relay {
7778
data: Buffer.from(signedVAAs[idx], "hex").toString("base64"),
7879
},
7980
},
80-
// TODO: Query the fee before
81-
[new Coin(this.coinDenom, 1)]
81+
[fee]
8282
);
8383

8484
msgs.push(msg);
@@ -181,18 +181,33 @@ export class TerraRelay implements Relay {
181181
logger.info("Querying terra for price info for priceId [" + priceId + "]");
182182

183183
const lcdClient = new LCDClient(this.lcdConfig);
184-
185-
const mk = new MnemonicKey({
186-
mnemonic: this.walletPrivateKey,
187-
});
188-
189184
return await lcdClient.wasm.contractQuery(this.contractAddress, {
190185
price_feed: {
191186
id: priceId,
192187
},
193188
});
194189
}
195190

191+
async getUpdateFee(hexVAAs: Array<string>): Promise<Coin> {
192+
const lcdClient = new LCDClient(this.lcdConfig);
193+
194+
let base64VAAs = [];
195+
for (let idx = 0; idx < hexVAAs.length; ++idx) {
196+
base64VAAs.push(Buffer.from(hexVAAs[idx], "hex").toString("base64"));
197+
}
198+
199+
let result = await lcdClient.wasm.contractQuery<Coin.Data>(
200+
this.contractAddress,
201+
{
202+
get_update_fee: {
203+
vaas: base64VAAs,
204+
},
205+
}
206+
);
207+
208+
return Coin.fromData(result);
209+
}
210+
196211
async getPayerInfo(): Promise<{ address: string; balance: bigint }> {
197212
const lcdClient = new LCDClient(this.lcdConfig);
198213

0 commit comments

Comments
 (0)