cosmwasm: accounting: Use cw_transcode for events
Use cw_transcode to ensure that event attribute values are always encoded as proper json, making it easier for clients to parse them back into structured data. This also lets us reuse the input messages for the events, reducing the number of different structs that we need to track.
This commit is contained in:
parent
5c41d343ca
commit
8777c22d32
|
@ -11,9 +11,11 @@ dependencies = [
|
||||||
"cosmwasm-schema",
|
"cosmwasm-schema",
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
"cw-storage-plus",
|
"cw-storage-plus",
|
||||||
|
"cw_transcode",
|
||||||
"hex",
|
"hex",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde-json-wasm",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2257,9 +2259,11 @@ dependencies = [
|
||||||
"cw-multi-test",
|
"cw-multi-test",
|
||||||
"cw-storage-plus",
|
"cw-storage-plus",
|
||||||
"cw2",
|
"cw2",
|
||||||
|
"cw_transcode",
|
||||||
"hex",
|
"hex",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde-json-wasm",
|
||||||
"serde_wormhole",
|
"serde_wormhole",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
|
|
|
@ -20,8 +20,9 @@ cosmwasm-schema = "1"
|
||||||
cosmwasm-std = "1"
|
cosmwasm-std = "1"
|
||||||
cosmwasm-storage = "1"
|
cosmwasm-storage = "1"
|
||||||
cw-storage-plus = "0.13.2"
|
cw-storage-plus = "0.13.2"
|
||||||
|
cw_transcode = "0.1.0"
|
||||||
cw2 = "0.13.2"
|
cw2 = "0.13.2"
|
||||||
hex = "0.4.3"
|
hex = { version = "0.4.3", features = ["serde"] }
|
||||||
schemars = "0.8.8"
|
schemars = "0.8.8"
|
||||||
serde = { version = "1.0.137", default-features = false, features = ["derive"] }
|
serde = { version = "1.0.137", default-features = false, features = ["derive"] }
|
||||||
serde_wormhole = "0.1.0"
|
serde_wormhole = "0.1.0"
|
||||||
|
@ -34,4 +35,5 @@ wormhole-core = { version = "0.1.0", features = ["schemars"] }
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
anyhow = { version = "1", features = ["backtrace"] }
|
anyhow = { version = "1", features = ["backtrace"] }
|
||||||
cw-multi-test = "0.13.2"
|
cw-multi-test = "0.13.2"
|
||||||
|
serde-json-wasm = "0.4"
|
||||||
wormhole-bindings = { version = "0.1", features = ["fake"] }
|
wormhole-bindings = { version = "0.1", features = ["fake"] }
|
||||||
|
|
|
@ -18,7 +18,7 @@ use tinyvec::{Array, TinyVec};
|
||||||
use wormhole::{
|
use wormhole::{
|
||||||
token::{Action, GovernancePacket, Message},
|
token::{Action, GovernancePacket, Message},
|
||||||
vaa::{self, Body, Header, Signature},
|
vaa::{self, Body, Header, Signature},
|
||||||
Address, Chain,
|
Chain,
|
||||||
};
|
};
|
||||||
use wormhole_bindings::WormholeQuery;
|
use wormhole_bindings::WormholeQuery;
|
||||||
|
|
||||||
|
@ -237,17 +237,9 @@ fn handle_observation(
|
||||||
// Now that the transfer has been committed, we don't need to keep it in the pending list.
|
// Now that the transfer has been committed, we don't need to keep it in the pending list.
|
||||||
key.remove(deps.storage);
|
key.remove(deps.storage);
|
||||||
|
|
||||||
Ok(Some(
|
cw_transcode::to_event(&o)
|
||||||
Event::new("Transfer")
|
.map(Some)
|
||||||
.add_attribute("tx_hash", o.tx_hash.to_base64())
|
.context("failed to transcode `Observation` to `Event`")
|
||||||
.add_attribute("timestamp", o.timestamp.to_string())
|
|
||||||
.add_attribute("nonce", o.nonce.to_string())
|
|
||||||
.add_attribute("emitter_chain", o.emitter_chain.to_string())
|
|
||||||
.add_attribute("emitter_address", Address(o.emitter_address).to_string())
|
|
||||||
.add_attribute("sequence", o.sequence.to_string())
|
|
||||||
.add_attribute("consistency_level", o.consistency_level.to_string())
|
|
||||||
.add_attribute("payload", o.payload.to_base64()),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modify_balance(
|
fn modify_balance(
|
||||||
|
|
|
@ -24,6 +24,8 @@ pub struct Observation {
|
||||||
pub emitter_chain: u16,
|
pub emitter_chain: u16,
|
||||||
|
|
||||||
// The address on the source chain that emitted this message.
|
// The address on the source chain that emitted this message.
|
||||||
|
#[serde(with = "hex")]
|
||||||
|
#[schemars(with = "String")]
|
||||||
pub emitter_address: [u8; 32],
|
pub emitter_address: [u8; 32],
|
||||||
|
|
||||||
// The sequence number of this observation.
|
// The sequence number of this observation.
|
||||||
|
|
|
@ -25,14 +25,20 @@ fn simple_modify() {
|
||||||
.modify_balance(modification, index, signatures)
|
.modify_balance(modification, index, signatures)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let evt = Event::new("wasm-ModifyBalance")
|
let evt = Event::new("wasm-Modification")
|
||||||
.add_attribute("sequence", m.sequence.to_string())
|
.add_attribute("sequence", serde_json_wasm::to_string(&m.sequence).unwrap())
|
||||||
.add_attribute("chain_id", m.chain_id.to_string())
|
.add_attribute("chain_id", serde_json_wasm::to_string(&m.chain_id).unwrap())
|
||||||
.add_attribute("token_chain", m.token_chain.to_string())
|
.add_attribute(
|
||||||
.add_attribute("token_address", m.token_address.to_string())
|
"token_chain",
|
||||||
.add_attribute("kind", m.kind.to_string())
|
serde_json_wasm::to_string(&m.token_chain).unwrap(),
|
||||||
.add_attribute("amount", m.amount)
|
)
|
||||||
.add_attribute("reason", m.reason.clone());
|
.add_attribute(
|
||||||
|
"token_address",
|
||||||
|
serde_json_wasm::to_string(&m.token_address).unwrap(),
|
||||||
|
)
|
||||||
|
.add_attribute("kind", serde_json_wasm::to_string(&m.kind).unwrap())
|
||||||
|
.add_attribute("amount", serde_json_wasm::to_string(&m.amount).unwrap())
|
||||||
|
.add_attribute("reason", serde_json_wasm::to_string(&m.reason).unwrap());
|
||||||
|
|
||||||
resp.assert_event(&evt);
|
resp.assert_event(&evt);
|
||||||
|
|
||||||
|
|
|
@ -776,15 +776,27 @@ fn emit_event_with_quorum() {
|
||||||
|
|
||||||
let (o, responses) = transfer_tokens(&wh, &mut contract, key, msg, index, quorum).unwrap();
|
let (o, responses) = transfer_tokens(&wh, &mut contract, key, msg, index, quorum).unwrap();
|
||||||
|
|
||||||
let expected = Event::new("wasm-Transfer")
|
let expected = Event::new("wasm-Observation")
|
||||||
.add_attribute("tx_hash", o.tx_hash.to_base64())
|
.add_attribute("tx_hash", serde_json_wasm::to_string(&o.tx_hash).unwrap())
|
||||||
.add_attribute("timestamp", o.timestamp.to_string())
|
.add_attribute(
|
||||||
.add_attribute("nonce", o.nonce.to_string())
|
"timestamp",
|
||||||
.add_attribute("emitter_chain", o.emitter_chain.to_string())
|
serde_json_wasm::to_string(&o.timestamp).unwrap(),
|
||||||
.add_attribute("emitter_address", Address(o.emitter_address).to_string())
|
)
|
||||||
.add_attribute("sequence", o.sequence.to_string())
|
.add_attribute("nonce", serde_json_wasm::to_string(&o.nonce).unwrap())
|
||||||
.add_attribute("consistency_level", o.consistency_level.to_string())
|
.add_attribute(
|
||||||
.add_attribute("payload", o.payload.to_base64());
|
"emitter_chain",
|
||||||
|
serde_json_wasm::to_string(&o.emitter_chain).unwrap(),
|
||||||
|
)
|
||||||
|
.add_attribute(
|
||||||
|
"emitter_address",
|
||||||
|
serde_json_wasm::to_string(&hex::encode(o.emitter_address)).unwrap(),
|
||||||
|
)
|
||||||
|
.add_attribute("sequence", serde_json_wasm::to_string(&o.sequence).unwrap())
|
||||||
|
.add_attribute(
|
||||||
|
"consistency_level",
|
||||||
|
serde_json_wasm::to_string(&o.consistency_level).unwrap(),
|
||||||
|
)
|
||||||
|
.add_attribute("payload", serde_json_wasm::to_string(&o.payload).unwrap());
|
||||||
|
|
||||||
assert_eq!(responses.len(), quorum);
|
assert_eq!(responses.len(), quorum);
|
||||||
for (i, r) in responses.into_iter().enumerate() {
|
for (i, r) in responses.into_iter().enumerate() {
|
||||||
|
|
|
@ -91,12 +91,9 @@ fn basic() {
|
||||||
assert_eq!(data, tx.data);
|
assert_eq!(data, tx.data);
|
||||||
assert_eq!(&digest[..], &*tx.digest);
|
assert_eq!(&digest[..], &*tx.digest);
|
||||||
resp.assert_event(
|
resp.assert_event(
|
||||||
&Event::new("wasm-CommitTransfer")
|
&Event::new("wasm-Transfer")
|
||||||
.add_attribute("key", key.to_string())
|
.add_attribute("key", serde_json_wasm::to_string(&key).unwrap())
|
||||||
.add_attribute("amount", data.amount.to_string())
|
.add_attribute("data", serde_json_wasm::to_string(&data).unwrap()),
|
||||||
.add_attribute("token_chain", data.token_chain.to_string())
|
|
||||||
.add_attribute("token_address", data.token_address.to_string())
|
|
||||||
.add_attribute("recipient_chain", data.recipient_chain.to_string()),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,12 +247,9 @@ fn transfer_with_payload() {
|
||||||
assert_eq!(data, tx.data);
|
assert_eq!(data, tx.data);
|
||||||
assert_eq!(&digest[..], &*tx.digest);
|
assert_eq!(&digest[..], &*tx.digest);
|
||||||
resp.assert_event(
|
resp.assert_event(
|
||||||
&Event::new("wasm-CommitTransfer")
|
&Event::new("wasm-Transfer")
|
||||||
.add_attribute("key", key.to_string())
|
.add_attribute("key", serde_json_wasm::to_string(&key).unwrap())
|
||||||
.add_attribute("amount", data.amount.to_string())
|
.add_attribute("data", serde_json_wasm::to_string(&data).unwrap()),
|
||||||
.add_attribute("token_chain", data.token_chain.to_string())
|
|
||||||
.add_attribute("token_address", data.token_address.to_string())
|
|
||||||
.add_attribute("recipient_chain", data.recipient_chain.to_string()),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ base64 = "0.13"
|
||||||
cosmwasm-schema = "1"
|
cosmwasm-schema = "1"
|
||||||
cosmwasm-std = "1"
|
cosmwasm-std = "1"
|
||||||
cw-storage-plus = "0.13.2"
|
cw-storage-plus = "0.13.2"
|
||||||
|
cw_transcode = "0.1.0"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
schemars = "0.8.8"
|
schemars = "0.8.8"
|
||||||
serde = { version = "1.0.137", default-features = false }
|
serde = { version = "1.0.137", default-features = false }
|
||||||
|
@ -26,3 +27,4 @@ thiserror = "1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
anyhow = { version = "1", features = ["backtrace"] }
|
anyhow = { version = "1", features = ["backtrace"] }
|
||||||
|
serde-json-wasm = "0.4"
|
||||||
|
|
|
@ -116,12 +116,7 @@ pub fn commit_transfer<C: CustomQuery>(deps: DepsMut<C>, t: Transfer) -> anyhow:
|
||||||
.save(deps.storage, dst.key, &dst.balance)
|
.save(deps.storage, dst.key, &dst.balance)
|
||||||
.context("failed to save updated destination account")?;
|
.context("failed to save updated destination account")?;
|
||||||
|
|
||||||
let evt = Event::new("CommitTransfer")
|
let evt = cw_transcode::to_event(&t).context("failed to transcode `Transfer` to `Event`")?;
|
||||||
.add_attribute("key", t.key.to_string())
|
|
||||||
.add_attribute("amount", t.data.amount.to_string())
|
|
||||||
.add_attribute("token_chain", t.data.token_chain.to_string())
|
|
||||||
.add_attribute("token_address", t.data.token_address.to_string())
|
|
||||||
.add_attribute("recipient_chain", t.data.recipient_chain.to_string());
|
|
||||||
|
|
||||||
TRANSFERS
|
TRANSFERS
|
||||||
.save(deps.storage, t.key, &t.data)
|
.save(deps.storage, t.key, &t.data)
|
||||||
|
@ -269,14 +264,7 @@ pub fn modify_balance<C: CustomQuery>(
|
||||||
.save(deps.storage, msg.sequence, &msg)
|
.save(deps.storage, msg.sequence, &msg)
|
||||||
.context("failed to store `Modification`")?;
|
.context("failed to store `Modification`")?;
|
||||||
|
|
||||||
Ok(Event::new("ModifyBalance")
|
cw_transcode::to_event(&msg).context("failed to transcode `Modification` to `Event`")
|
||||||
.add_attribute("sequence", msg.sequence.to_string())
|
|
||||||
.add_attribute("chain_id", msg.chain_id.to_string())
|
|
||||||
.add_attribute("token_chain", msg.token_chain.to_string())
|
|
||||||
.add_attribute("token_address", msg.token_address.to_string())
|
|
||||||
.add_attribute("kind", msg.kind.to_string())
|
|
||||||
.add_attribute("amount", msg.amount)
|
|
||||||
.add_attribute("reason", msg.reason))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Query the balance for the account associated with `key`.
|
/// Query the balance for the account associated with `key`.
|
||||||
|
@ -471,22 +459,10 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert_eq!(tx.data.amount, *query_balance(deps.as_ref(), dst).unwrap());
|
assert_eq!(tx.data.amount, *query_balance(deps.as_ref(), dst).unwrap());
|
||||||
|
|
||||||
assert_eq!(evt.ty, "CommitTransfer");
|
let expected = Event::new("Transfer")
|
||||||
assert_eq!(evt.attributes.len(), 5);
|
.add_attribute("key", serde_json_wasm::to_string(&tx.key).unwrap())
|
||||||
|
.add_attribute("data", serde_json_wasm::to_string(&tx.data).unwrap());
|
||||||
let attrs = evt
|
assert_eq!(expected, evt);
|
||||||
.attributes
|
|
||||||
.into_iter()
|
|
||||||
.map(|attr| (attr.key, attr.value))
|
|
||||||
.collect::<BTreeMap<_, _>>();
|
|
||||||
assert_eq!(attrs["key"], tx.key.to_string());
|
|
||||||
assert_eq!(attrs["amount"], tx.data.amount.to_string());
|
|
||||||
assert_eq!(attrs["token_chain"], tx.data.token_chain.to_string());
|
|
||||||
assert_eq!(attrs["token_address"], tx.data.token_address.to_string());
|
|
||||||
assert_eq!(
|
|
||||||
attrs["recipient_chain"],
|
|
||||||
tx.data.recipient_chain.to_string()
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(tx.data, query_transfer(deps.as_ref(), tx.key).unwrap());
|
assert_eq!(tx.data, query_transfer(deps.as_ref(), tx.key).unwrap());
|
||||||
}
|
}
|
||||||
|
@ -870,21 +846,21 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(m, query_modification(deps.as_ref(), m.sequence).unwrap());
|
assert_eq!(m, query_modification(deps.as_ref(), m.sequence).unwrap());
|
||||||
|
|
||||||
assert_eq!(evt.ty, "ModifyBalance");
|
let expected = Event::new("Modification")
|
||||||
assert_eq!(evt.attributes.len(), 7);
|
.add_attribute("sequence", serde_json_wasm::to_string(&m.sequence).unwrap())
|
||||||
|
.add_attribute("chain_id", serde_json_wasm::to_string(&m.chain_id).unwrap())
|
||||||
let attrs = evt
|
.add_attribute(
|
||||||
.attributes
|
"token_chain",
|
||||||
.into_iter()
|
serde_json_wasm::to_string(&m.token_chain).unwrap(),
|
||||||
.map(|attr| (attr.key, attr.value))
|
)
|
||||||
.collect::<BTreeMap<_, _>>();
|
.add_attribute(
|
||||||
assert_eq!(attrs["sequence"], m.sequence.to_string());
|
"token_address",
|
||||||
assert_eq!(attrs["chain_id"], m.chain_id.to_string());
|
serde_json_wasm::to_string(&m.token_address).unwrap(),
|
||||||
assert_eq!(attrs["token_chain"], m.token_chain.to_string());
|
)
|
||||||
assert_eq!(attrs["token_address"], m.token_address.to_string());
|
.add_attribute("kind", serde_json_wasm::to_string(&m.kind).unwrap())
|
||||||
assert_eq!(attrs["kind"], m.kind.to_string());
|
.add_attribute("amount", serde_json_wasm::to_string(&m.amount).unwrap())
|
||||||
assert_eq!(attrs["amount"], m.amount.to_string());
|
.add_attribute("reason", serde_json_wasm::to_string(&m.reason).unwrap());
|
||||||
assert_eq!(attrs["reason"], m.reason);
|
assert_eq!(expected, evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue