Skip to content

Commit 3cea0ae

Browse files
authored
Merge pull request #968 from CosmWasm/custom-events
Custom events
2 parents f275d78 + 6c6f19a commit 3cea0ae

File tree

17 files changed

+97
-21
lines changed

17 files changed

+97
-21
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to
99
### Added
1010

1111
- cosmwasm-std: Implement `Sub` and `SubAssign` for `Uint128`
12+
- cosmwasm-std: Implement custom events for contract execution results
1213

1314
### Removed
1415

@@ -47,6 +48,8 @@ and this project adheres to
4748
- cosmwasm-std: Add `SubMsg` constructors: `::new()`, `::reply_on_error()`,
4849
`::reply_on_success()`, `::reply_always()`; Add `with_gas_limit` to add a gas
4950
limit to any those constructors ([#961]).
51+
- cosmwasm-std: Change `Event`'s constructor - it no longer takes a vector of
52+
attributes and instead constructs an empty one
5053

5154
[#961]: https://github.com/CosmWasm/cosmwasm/pull/961
5255

contracts/burner/src/contract.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub fn migrate(deps: DepsMut, env: Env, msg: MigrateMsg) -> StdResult<Response>
4242
Ok(Response {
4343
messages: vec![SubMsg::new(send)],
4444
attributes: vec![attr("action", "burn"), attr("payout", msg.payout)],
45+
events: vec![],
4546
data: Some(data_msg.into()),
4647
})
4748
}

contracts/hackatom/src/contract.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use sha2::{Digest, Sha256};
22

33
use cosmwasm_std::{
44
entry_point, from_slice, to_binary, to_vec, Addr, AllBalanceResponse, Api, BankMsg,
5-
CanonicalAddr, Deps, DepsMut, Env, MessageInfo, QueryRequest, QueryResponse, Response,
5+
CanonicalAddr, Deps, DepsMut, Env, Event, MessageInfo, QueryRequest, QueryResponse, Response,
66
StdError, StdResult, WasmQuery,
77
};
88

@@ -93,6 +93,7 @@ fn do_release(deps: DepsMut, env: Env, info: MessageInfo) -> Result<Response, Ha
9393
let mut resp = Response::new();
9494
resp.add_attribute("action", "release");
9595
resp.add_attribute("destination", to_addr.clone());
96+
resp.add_event(Event::new("hackatom").attr("action", "release"));
9697
resp.add_message(BankMsg::Send {
9798
to_address: to_addr.into(),
9899
amount: balance,

contracts/ibc-reflect/schema/acknowledgement_msg_balances.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "http://json-schema.org/draft-07/schema#",
33
"title": "AcknowledgementMsgBalances",
4-
"description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult<Response> = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"data\":null}}\"#.to_vec()); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult<Response> = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#.to_vec()); ```",
4+
"description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult<Response> = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"events\":[],\"data\":null}}\"#.to_vec()); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult<Response> = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#.to_vec()); ```",
55
"anyOf": [
66
{
77
"type": "object",

contracts/ibc-reflect/schema/acknowledgement_msg_dispatch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "http://json-schema.org/draft-07/schema#",
33
"title": "AcknowledgementMsgDispatch",
4-
"description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult<Response> = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"data\":null}}\"#.to_vec()); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult<Response> = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#.to_vec()); ```",
4+
"description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult<Response> = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"events\":[],\"data\":null}}\"#.to_vec()); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult<Response> = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#.to_vec()); ```",
55
"anyOf": [
66
{
77
"type": "object",

contracts/ibc-reflect/schema/acknowledgement_msg_who_am_i.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "http://json-schema.org/draft-07/schema#",
33
"title": "AcknowledgementMsgWhoAmI",
4-
"description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult<Response> = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"data\":null}}\"#.to_vec()); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult<Response> = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#.to_vec()); ```",
4+
"description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult<Response> = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"events\":[],\"data\":null}}\"#.to_vec()); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult<Response> = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#.to_vec()); ```",
55
"anyOf": [
66
{
77
"type": "object",

contracts/ibc-reflect/src/contract.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use cosmwasm_std::{
22
attr, entry_point, from_slice, to_binary, wasm_execute, BankMsg, Binary, ContractResult,
33
CosmosMsg, Deps, DepsMut, Empty, Env, Event, IbcAcknowledgement, IbcBasicResponse, IbcChannel,
4-
IbcOrder, IbcPacket, IbcReceiveResponse, MessageInfo, Order, QueryResponse, Reply,
5-
Response, StdError, StdResult, SubMsg, SubcallResponse, WasmMsg,
4+
IbcOrder, IbcPacket, IbcReceiveResponse, MessageInfo, Order, QueryResponse, Reply, Response,
5+
StdError, StdResult, SubMsg, SubcallResponse, WasmMsg,
66
};
77

88
use crate::msg::{

contracts/reflect/schema/response_for__custom_msg.json

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{
22
"$schema": "http://json-schema.org/draft-07/schema#",
33
"title": "Response_for_CustomMsg",
4-
"description": "A response of a contract entry point, such as `instantiate`, `execute` or `migrate`.\n\nThis type can be constructed directly at the end of the call. Alternatively a mutable response instance can be created early in the contract's logic and incrementally be updated.\n\n## Examples\n\nDirect:\n\n``` # use cosmwasm_std::{Binary, DepsMut, Env, MessageInfo}; # type InstantiateMsg = (); # use cosmwasm_std::{attr, Response, StdResult};\n\npub fn instantiate( deps: DepsMut, _env: Env, _info: MessageInfo, msg: InstantiateMsg, ) -> StdResult<Response> { // ...\n\nOk(Response { messages: vec![], attributes: vec![attr(\"action\", \"instantiate\")], data: None, }) } ```\n\nMutating:\n\n``` # use cosmwasm_std::{coins, BankMsg, Binary, DepsMut, Env, MessageInfo, SubMsg}; # type InstantiateMsg = (); # type MyError = (); # use cosmwasm_std::Response;\n\npub fn instantiate( deps: DepsMut, _env: Env, info: MessageInfo, msg: InstantiateMsg, ) -> Result<Response, MyError> { let mut response = Response::new(); // ... response.add_attribute(\"Let the\", \"hacking begin\"); // ... response.add_message(BankMsg::Send { to_address: String::from(\"recipient\"), amount: coins(128, \"uint\"), }); response.add_attribute(\"foo\", \"bar\"); // ... response.set_data(Binary::from(b\"the result data\")); Ok(response) } ```",
4+
"description": "A response of a contract entry point, such as `instantiate`, `execute` or `migrate`.\n\nThis type can be constructed directly at the end of the call. Alternatively a mutable response instance can be created early in the contract's logic and incrementally be updated.\n\n## Examples\n\nDirect:\n\n``` # use cosmwasm_std::{Binary, DepsMut, Env, MessageInfo}; # type InstantiateMsg = (); # use cosmwasm_std::{attr, Response, StdResult};\n\npub fn instantiate( deps: DepsMut, _env: Env, _info: MessageInfo, msg: InstantiateMsg, ) -> StdResult<Response> { // ...\n\nOk(Response { messages: vec![], attributes: vec![attr(\"action\", \"instantiate\")], events: vec![], data: None, }) } ```\n\nMutating:\n\n``` # use cosmwasm_std::{coins, BankMsg, Binary, DepsMut, Env, MessageInfo, SubMsg}; # type InstantiateMsg = (); # type MyError = (); # use cosmwasm_std::Response;\n\npub fn instantiate( deps: DepsMut, _env: Env, info: MessageInfo, msg: InstantiateMsg, ) -> Result<Response, MyError> { let mut response = Response::new(); // ... response.add_attribute(\"Let the\", \"hacking begin\"); // ... response.add_message(BankMsg::Send { to_address: String::from(\"recipient\"), amount: coins(128, \"uint\"), }); response.add_attribute(\"foo\", \"bar\"); // ... response.set_data(Binary::from(b\"the result data\")); Ok(response) } ```",
55
"type": "object",
66
"required": [
77
"attributes",
8+
"events",
89
"messages"
910
],
1011
"properties": {
@@ -25,6 +26,12 @@
2526
}
2627
]
2728
},
29+
"events": {
30+
"type": "array",
31+
"items": {
32+
"$ref": "#/definitions/Event"
33+
}
34+
},
2835
"messages": {
2936
"description": "Optional list of messages to pass. These will be executed in order. If the ReplyOn variant matches the result (Always, Success on Ok, Error on Err), the runtime will invoke this contract's `reply` entry point after execution. Otherwise, they act like \"fire and forget\". Use `SubMsg::new` to create messages with the older \"fire and forget\" semantics.",
3037
"type": "array",
@@ -305,6 +312,26 @@
305312
}
306313
]
307314
},
315+
"Event": {
316+
"description": "A full Cosmos SDK event as documented in https://docs.cosmos.network/v0.42/core/events.html.\n\nThis version uses string attributes (similar to https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/base/abci/v1beta1/abci.proto#L56-L70), which then get magically converted to bytes for Tendermint somewhere between the Rust-Go interface, JSON deserialization and the `NewEvent` call in Cosmos SDK.",
317+
"type": "object",
318+
"required": [
319+
"attributes",
320+
"type"
321+
],
322+
"properties": {
323+
"attributes": {
324+
"type": "array",
325+
"items": {
326+
"$ref": "#/definitions/Attribute"
327+
}
328+
},
329+
"type": {
330+
"description": "The event type. This is renamed to \"kind\" because \"type\" is reserved in Rust. This sucks, we know.",
331+
"type": "string"
332+
}
333+
}
334+
},
308335
"IbcMsg": {
309336
"description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)",
310337
"anyOf": [

contracts/reflect/src/contract.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub fn try_reflect(
5757
let res = Response {
5858
messages,
5959
attributes: vec![attr("action", "reflect")],
60+
events: vec![],
6061
data: None,
6162
};
6263
Ok(res)
@@ -82,6 +83,7 @@ pub fn try_reflect_subcall(
8283
let res = Response {
8384
messages: msgs,
8485
attributes: vec![attr("action", "reflect_subcall")],
86+
events: vec![],
8587
data: None,
8688
};
8789
Ok(res)
@@ -434,7 +436,7 @@ mod tests {
434436

435437
let id = 123u64;
436438
let data = Binary::from(b"foobar");
437-
let events = vec![Event::new("message", vec![attr("signer", "caller-addr")])];
439+
let events = vec![Event::new("message").attr("signer", "caller-addr")];
438440
let result = ContractResult::Ok(SubcallResponse {
439441
events: events.clone(),
440442
data: Some(data.clone()),

contracts/reflect/tests/integration.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
//! 4. Anywhere you see query(&deps, ...) you must replace it with query(&mut deps, ...)
1919
2020
use cosmwasm_std::{
21-
attr, coin, coins, from_binary, BankMsg, Binary, Coin, ContractResult, Event, Reply, Response,
21+
coin, coins, from_binary, BankMsg, Binary, Coin, ContractResult, Event, Reply, Response,
2222
StakingMsg, SubMsg, SubcallResponse, SystemResult,
2323
};
2424
use cosmwasm_vm::{
@@ -225,7 +225,7 @@ fn reply_and_query() {
225225

226226
let id = 123u64;
227227
let data = Binary::from(b"foobar");
228-
let events = vec![Event::new("message", vec![attr("signer", "caller-addr")])];
228+
let events = vec![Event::new("message").attr("signer", "caller-addr")];
229229
let result = ContractResult::Ok(SubcallResponse {
230230
events: events.clone(),
231231
data: Some(data.clone()),

0 commit comments

Comments
 (0)