Skip to content

Commit f9f3feb

Browse files
committed
Avoid the all_balances query in hackathon
1 parent a26befa commit f9f3feb

File tree

6 files changed

+129
-159
lines changed

6 files changed

+129
-159
lines changed

contracts/hackatom/schema/hackatom.json

Lines changed: 9 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,22 @@
2525
"title": "ExecuteMsg",
2626
"oneOf": [
2727
{
28-
"description": "Releasing all funds in the contract to the beneficiary. This is the only \"proper\" action of this demo contract.",
28+
"description": "Releasing all funds of the given denom in the contract to the beneficiary. This is the only \"proper\" action of this demo contract.",
2929
"type": "object",
3030
"required": [
3131
"release"
3232
],
3333
"properties": {
3434
"release": {
3535
"type": "object",
36+
"required": [
37+
"denom"
38+
],
39+
"properties": {
40+
"denom": {
41+
"type": "string"
42+
}
43+
},
3644
"additionalProperties": false
3745
}
3846
},
@@ -166,28 +174,6 @@
166174
},
167175
"additionalProperties": false
168176
},
169-
{
170-
"description": "This returns cosmwasm_std::AllBalanceResponse to demo use of the querier",
171-
"type": "object",
172-
"required": [
173-
"other_balance"
174-
],
175-
"properties": {
176-
"other_balance": {
177-
"type": "object",
178-
"required": [
179-
"address"
180-
],
181-
"properties": {
182-
"address": {
183-
"type": "string"
184-
}
185-
},
186-
"additionalProperties": false
187-
}
188-
},
189-
"additionalProperties": false
190-
},
191177
{
192178
"description": "Recurse will execute a query into itself up to depth-times and return Each step of the recursion may perform some extra work to test gas metering (`work` rounds of sha256 on contract). Now that we have Env, we can auto-calculate the address to recurse into",
193179
"type": "object",
@@ -323,46 +309,6 @@
323309
},
324310
"additionalProperties": false
325311
},
326-
"other_balance": {
327-
"$schema": "http://json-schema.org/draft-07/schema#",
328-
"title": "AllBalanceResponse",
329-
"type": "object",
330-
"required": [
331-
"amount"
332-
],
333-
"properties": {
334-
"amount": {
335-
"description": "Returns all non-zero coins held by this account.",
336-
"type": "array",
337-
"items": {
338-
"$ref": "#/definitions/Coin"
339-
}
340-
}
341-
},
342-
"additionalProperties": false,
343-
"definitions": {
344-
"Coin": {
345-
"type": "object",
346-
"required": [
347-
"amount",
348-
"denom"
349-
],
350-
"properties": {
351-
"amount": {
352-
"$ref": "#/definitions/Uint128"
353-
},
354-
"denom": {
355-
"type": "string"
356-
}
357-
},
358-
"additionalProperties": false
359-
},
360-
"Uint128": {
361-
"description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```",
362-
"type": "string"
363-
}
364-
}
365-
},
366312
"recurse": {
367313
"$schema": "http://json-schema.org/draft-07/schema#",
368314
"title": "RecurseResponse",

contracts/hackatom/schema/raw/execute.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@
33
"title": "ExecuteMsg",
44
"oneOf": [
55
{
6-
"description": "Releasing all funds in the contract to the beneficiary. This is the only \"proper\" action of this demo contract.",
6+
"description": "Releasing all funds of the given denom in the contract to the beneficiary. This is the only \"proper\" action of this demo contract.",
77
"type": "object",
88
"required": [
99
"release"
1010
],
1111
"properties": {
1212
"release": {
1313
"type": "object",
14+
"required": [
15+
"denom"
16+
],
17+
"properties": {
18+
"denom": {
19+
"type": "string"
20+
}
21+
},
1422
"additionalProperties": false
1523
}
1624
},

contracts/hackatom/schema/raw/query.json

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,6 @@
1616
},
1717
"additionalProperties": false
1818
},
19-
{
20-
"description": "This returns cosmwasm_std::AllBalanceResponse to demo use of the querier",
21-
"type": "object",
22-
"required": [
23-
"other_balance"
24-
],
25-
"properties": {
26-
"other_balance": {
27-
"type": "object",
28-
"required": [
29-
"address"
30-
],
31-
"properties": {
32-
"address": {
33-
"type": "string"
34-
}
35-
},
36-
"additionalProperties": false
37-
}
38-
},
39-
"additionalProperties": false
40-
},
4119
{
4220
"description": "Recurse will execute a query into itself up to depth-times and return Each step of the recursion may perform some extra work to test gas metering (`work` rounds of sha256 on contract). Now that we have Env, we can auto-calculate the address to recurse into",
4321
"type": "object",

contracts/hackatom/src/contract.rs

Lines changed: 85 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use sha2::{Digest, Sha256};
22

33
use cosmwasm_std::{
4-
entry_point, from_json, to_json_binary, to_json_vec, Addr, AllBalanceResponse, Api, BankMsg,
5-
BankQuery, CanonicalAddr, Deps, DepsMut, Env, Event, MessageInfo, MigrateInfo, QueryRequest,
6-
QueryResponse, Response, StdError, StdResult, WasmMsg, WasmQuery,
4+
entry_point, from_json, to_json_binary, to_json_vec, Addr, Api, BankMsg, CanonicalAddr, Deps,
5+
DepsMut, Env, Event, MessageInfo, MigrateInfo, QueryRequest, QueryResponse, Response, StdError,
6+
StdResult, WasmMsg, WasmQuery,
77
};
88

99
use crate::errors::HackError;
@@ -82,7 +82,7 @@ pub fn execute(
8282
msg: ExecuteMsg,
8383
) -> Result<Response, HackError> {
8484
match msg {
85-
ExecuteMsg::Release {} => do_release(deps, env, info),
85+
ExecuteMsg::Release { denom } => do_release(deps, env, info, denom),
8686
ExecuteMsg::CpuLoop {} => do_cpu_loop(),
8787
ExecuteMsg::StorageLoop {} => do_storage_loop(deps),
8888
ExecuteMsg::MemoryLoop {} => do_memory_loop(),
@@ -93,7 +93,12 @@ pub fn execute(
9393
}
9494
}
9595

96-
fn do_release(deps: DepsMut, env: Env, info: MessageInfo) -> Result<Response, HackError> {
96+
fn do_release(
97+
deps: DepsMut,
98+
env: Env,
99+
info: MessageInfo,
100+
denom: String,
101+
) -> Result<Response, HackError> {
97102
let data = deps
98103
.storage
99104
.get(CONFIG_KEY)
@@ -102,16 +107,15 @@ fn do_release(deps: DepsMut, env: Env, info: MessageInfo) -> Result<Response, Ha
102107

103108
if info.sender == state.verifier {
104109
let to_addr = state.beneficiary;
105-
#[allow(deprecated)]
106-
let balance = deps.querier.query_all_balances(env.contract.address)?;
110+
let balance = deps.querier.query_balance(env.contract.address, denom)?;
107111

108112
let resp = Response::new()
109113
.add_attribute("action", "release")
110114
.add_attribute("destination", to_addr.clone())
111115
.add_event(Event::new("hackatom").add_attribute("action", "release"))
112116
.add_message(BankMsg::Send {
113117
to_address: to_addr.into(),
114-
amount: balance,
118+
amount: vec![balance],
115119
})
116120
.set_data([0xF0, 0x0B, 0xAA]);
117121
Ok(resp)
@@ -250,7 +254,6 @@ fn do_user_errors_in_api_calls(api: &dyn Api) -> Result<Response, HackError> {
250254
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<QueryResponse> {
251255
match msg {
252256
QueryMsg::Verifier {} => to_json_binary(&query_verifier(deps)?),
253-
QueryMsg::OtherBalance { address } => to_json_binary(&query_other_balance(deps, address)?),
254257
QueryMsg::Recurse { depth, work } => {
255258
to_json_binary(&query_recurse(deps, depth, work, env.contract.address)?)
256259
}
@@ -269,12 +272,6 @@ fn query_verifier(deps: Deps) -> StdResult<VerifierResponse> {
269272
})
270273
}
271274

272-
#[allow(deprecated)]
273-
fn query_other_balance(deps: Deps, address: String) -> StdResult<AllBalanceResponse> {
274-
deps.querier
275-
.query(&BankQuery::AllBalances { address }.into())
276-
}
277-
278275
fn query_recurse(deps: Deps, depth: u32, work: u32, contract: Addr) -> StdResult<RecurseResponse> {
279276
// perform all hashes as requested
280277
let mut hashed: Vec<u8> = contract.as_str().into();
@@ -308,12 +305,9 @@ fn query_int() -> IntResponse {
308305
#[cfg(test)]
309306
mod tests {
310307
use super::*;
311-
use cosmwasm_std::testing::{
312-
message_info, mock_dependencies, mock_dependencies_with_balances, mock_env,
313-
MOCK_CONTRACT_ADDR,
314-
};
308+
use cosmwasm_std::testing::{message_info, mock_dependencies, mock_env, MOCK_CONTRACT_ADDR};
315309
// import trait Storage to get access to read
316-
use cosmwasm_std::{coins, Binary, Storage, SubMsg};
310+
use cosmwasm_std::{coin, coins, Binary, Storage, SubMsg};
317311

318312
#[test]
319313
fn proper_initialization() {
@@ -440,21 +434,6 @@ mod tests {
440434
);
441435
}
442436

443-
#[test]
444-
fn querier_callbacks_work() {
445-
let rich_addr = String::from("foobar");
446-
let rich_balance = coins(10000, "gold");
447-
let deps = mock_dependencies_with_balances(&[(&rich_addr, &rich_balance)]);
448-
449-
// querying with balance gets the balance
450-
let bal = query_other_balance(deps.as_ref(), rich_addr).unwrap();
451-
assert_eq!(bal.amount, rich_balance);
452-
453-
// querying other accounts gets none
454-
let bal = query_other_balance(deps.as_ref(), String::from("someone else")).unwrap();
455-
assert_eq!(bal.amount, vec![]);
456-
}
457-
458437
#[test]
459438
fn execute_release_works() {
460439
let mut deps = mock_dependencies();
@@ -484,7 +463,9 @@ mod tests {
484463
deps.as_mut(),
485464
mock_env(),
486465
execute_info,
487-
ExecuteMsg::Release {},
466+
ExecuteMsg::Release {
467+
denom: "earth".to_string(),
468+
},
488469
)
489470
.unwrap();
490471
assert_eq!(execute_res.messages.len(), 1);
@@ -503,6 +484,71 @@ mod tests {
503484
assert_eq!(execute_res.data, Some(vec![0xF0, 0x0B, 0xAA].into()));
504485
}
505486

487+
#[test]
488+
fn execute_release_can_be_called_multiple_times() {
489+
let mut deps = mock_dependencies();
490+
491+
// initialize the store
492+
let creator = deps.api.addr_make("creator");
493+
let verifier = deps.api.addr_make("verifies");
494+
let beneficiary = deps.api.addr_make("benefits");
495+
496+
let instantiate_msg = InstantiateMsg {
497+
verifier: verifier.to_string(),
498+
beneficiary: beneficiary.to_string(),
499+
};
500+
let init_amount = vec![coin(1000, "earth"), coin(70, "sun")];
501+
let info = message_info(&creator, &init_amount);
502+
instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap();
503+
504+
// balance changed in init
505+
deps.querier
506+
.bank
507+
.update_balance(MOCK_CONTRACT_ADDR, init_amount);
508+
509+
// beneficiary can release it
510+
let execute_info = message_info(&verifier, &[]);
511+
let execute_res = execute(
512+
deps.as_mut(),
513+
mock_env(),
514+
execute_info,
515+
ExecuteMsg::Release {
516+
denom: "sun".to_string(),
517+
},
518+
)
519+
.unwrap();
520+
assert_eq!(execute_res.messages.len(), 1);
521+
let msg = execute_res.messages.first().expect("no message");
522+
assert_eq!(
523+
msg,
524+
&SubMsg::new(BankMsg::Send {
525+
to_address: beneficiary.to_string(),
526+
amount: coins(70, "sun"),
527+
}),
528+
);
529+
530+
// beneficiary can release it again
531+
let execute_info = message_info(&verifier, &[]);
532+
let execute_res = execute(
533+
deps.as_mut(),
534+
mock_env(),
535+
execute_info,
536+
ExecuteMsg::Release {
537+
denom: "earth".to_string(),
538+
},
539+
)
540+
.unwrap();
541+
assert_eq!(execute_res.messages.len(), 1);
542+
let msg = execute_res.messages.first().expect("no message");
543+
assert_eq!(
544+
msg,
545+
&SubMsg::new(BankMsg::Send {
546+
to_address: beneficiary.to_string(),
547+
amount: coins(1000, "earth"),
548+
}),
549+
);
550+
}
551+
506552
#[test]
507553
fn execute_release_fails_for_wrong_sender() {
508554
let mut deps = mock_dependencies();
@@ -532,7 +578,9 @@ mod tests {
532578
deps.as_mut(),
533579
mock_env(),
534580
execute_info,
535-
ExecuteMsg::Release {},
581+
ExecuteMsg::Release {
582+
denom: "earth".to_string(),
583+
},
536584
);
537585
assert_eq!(execute_res.unwrap_err(), HackError::Unauthorized {});
538586

contracts/hackatom/src/msg.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ pub enum SudoMsg {
3535
// https://github.com/cosmwasm/wasmd/issues/8#issuecomment-576146751
3636
#[cw_serde]
3737
pub enum ExecuteMsg {
38-
/// Releasing all funds in the contract to the beneficiary. This is the only "proper" action of this demo contract.
39-
Release {},
38+
/// Releasing all funds of the given denom in the contract to the beneficiary.
39+
/// This is the only "proper" action of this demo contract.
40+
Release { denom: String },
4041
/// Infinite loop to burn cpu cycles (only run when metering is enabled)
4142
CpuLoop {},
4243
/// Infinite loop making storage calls (to test when their limit hits)
@@ -61,9 +62,6 @@ pub enum QueryMsg {
6162
/// use to ensure query path works in integration tests
6263
#[returns(VerifierResponse)]
6364
Verifier {},
64-
/// This returns cosmwasm_std::AllBalanceResponse to demo use of the querier
65-
#[returns(cosmwasm_std::AllBalanceResponse)]
66-
OtherBalance { address: String },
6765
/// Recurse will execute a query into itself up to depth-times and return
6866
/// Each step of the recursion may perform some extra work to test gas metering
6967
/// (`work` rounds of sha256 on contract).

0 commit comments

Comments
 (0)