Skip to content

Commit 996b188

Browse files
Add mint event with mux support and other memo types to specs (#1555)
### What Add a new Mint event with muxed address support. Add events to specs for other memo types that can occur with payments from classic. ### Why The mint event should be defined so that contract developers can choose to emit a mint event to a destination with a muxed id. The specs should contain all of the event structures that an ingester could potentially see, including when other memo types are in use. ### Tests It wasn't possible to add comparison tests for the mint muxed event, or the mint memo string and bytes to_muxed_id types, to confirm the events are identical. This is because the soroban-env doesn't allow us to trigger those events because they are only generated by the classic transaction processing. For this reason @dmkozh @sisuresh please take great care to review the events being added. I've written them based on CAP-67, but we've had bugs in the past arise out of out-dated CAPs, so your help in validating they match core's implementation is much appreciated. Close #1554
1 parent 8da5d62 commit 996b188

9 files changed

Lines changed: 389 additions & 355 deletions

File tree

soroban-token-sdk/src/events.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub struct Approve {
1111
}
1212

1313
#[contractevent(topics = ["transfer"], data_format = "single-value")]
14-
pub struct TransferLegacy {
14+
pub struct TransferWithAmountOnly {
1515
#[topic]
1616
pub from: Address,
1717
#[topic]
@@ -37,9 +37,17 @@ pub struct Burn {
3737
}
3838

3939
#[contractevent(topics = ["mint"], data_format = "single-value")]
40+
pub struct MintWithAmountOnly {
41+
#[topic]
42+
pub to: Address,
43+
pub amount: i128,
44+
}
45+
46+
#[contractevent(topics = ["mint"], data_format = "map")]
4047
pub struct Mint {
4148
#[topic]
4249
pub to: Address,
50+
pub to_muxed_id: Option<u64>,
4351
pub amount: i128,
4452
}
4553

soroban-token-sdk/src/tests/events.rs

Lines changed: 82 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ extern crate std;
33
use core::i64;
44
use std::rc::Rc;
55

6-
use crate::events::{Approve, Burn, Clawback, Mint, Transfer, TransferLegacy};
6+
use crate::events::{
7+
Approve, Burn, Clawback, Mint, MintWithAmountOnly, Transfer, TransferWithAmountOnly,
8+
};
79
use soroban_sdk::{
810
contract, symbol_short,
911
testutils::{Address as _, Events as _, MuxedAddress as _},
@@ -66,15 +68,15 @@ fn test_approve() {
6668
}
6769

6870
#[test]
69-
fn test_transfer_legacy() {
71+
fn test_transfer_with_amount_only() {
7072
let env = Env::default();
7173
env.mock_all_auths();
7274

7375
let from = Address::generate(&env);
7476
let to = Address::generate(&env);
7577
let amount = 123;
7678

77-
let event = TransferLegacy {
79+
let event = TransferWithAmountOnly {
7880
from: from.clone(),
7981
to: to.clone(),
8082
amount,
@@ -154,9 +156,9 @@ fn test_transfer_without_id() {
154156

155157
// No comparison is made with the Stellar Asset Contract for publishing Transfer with a
156158
// MuxedAddress that does not contain an ID, because the Stellar Asset Contract for legacy
157-
// reasons, to minimise the changes to its behavior over time, still publishes TransferLegacy
158-
// in this case. See [`test_transfer_with_id`] for a test that exercises Transfer in the case
159-
// that the Stellar Asset contract does publish that event.
159+
// reasons, to minimise the changes to its behavior over time, still publishes
160+
// TransferWithAmountOnly in this case. See [`test_transfer_with_id`] for a test that exercises
161+
// Transfer in the case that the Stellar Asset contract does publish that event.
160162
}
161163

162164
#[test]
@@ -296,14 +298,14 @@ fn test_burn() {
296298
}
297299

298300
#[test]
299-
fn test_mint() {
301+
fn test_mint_with_amount_only() {
300302
let env = Env::default();
301303
env.mock_all_auths();
302304

303305
let to = Address::generate(&env);
304306
let amount = 123;
305307

306-
let event = Mint {
308+
let event = MintWithAmountOnly {
307309
to: to.clone(),
308310
amount,
309311
};
@@ -342,6 +344,78 @@ fn test_mint() {
342344
);
343345
}
344346

347+
#[test]
348+
fn test_mint_without_id() {
349+
let env = Env::default();
350+
env.mock_all_auths();
351+
352+
let to: MuxedAddress = MuxedAddress::generate(&env).address().into();
353+
let amount = 123;
354+
355+
let event = Mint {
356+
to: to.address(),
357+
to_muxed_id: to.id(),
358+
amount,
359+
};
360+
361+
// Verify the event publishes the expected topics and data.
362+
let topics = (symbol_short!("mint"), to.address());
363+
let data = Map::<Symbol, Val>::from_array(
364+
&env,
365+
[
366+
(Symbol::new(&env, "to_muxed_id"), Val::VOID.to_val()),
367+
(Symbol::new(&env, "amount"), amount.into_val(&env)),
368+
],
369+
);
370+
371+
let id = env.register(Contract, ());
372+
env.as_contract(&id, || event.publish(&env));
373+
let token_events = env.events().all();
374+
assert_eq!(
375+
token_events,
376+
vec![
377+
&env,
378+
(id.clone(), topics.into_val(&env), data.into_val(&env))
379+
]
380+
);
381+
}
382+
383+
#[test]
384+
fn test_mint_with_id() {
385+
let env = Env::default();
386+
env.mock_all_auths();
387+
388+
let to = MuxedAddress::generate(&env);
389+
let amount = 123;
390+
391+
let event = Mint {
392+
to: to.address(),
393+
to_muxed_id: to.id(),
394+
amount,
395+
};
396+
397+
// Verify the event publishes the expected topics and data.
398+
let topics = (symbol_short!("mint"), to.address());
399+
let data = Map::<Symbol, Val>::from_array(
400+
&env,
401+
[
402+
(Symbol::new(&env, "to_muxed_id"), to.id().into_val(&env)),
403+
(Symbol::new(&env, "amount"), amount.into_val(&env)),
404+
],
405+
);
406+
407+
let id = env.register(Contract, ());
408+
env.as_contract(&id, || event.publish(&env));
409+
let token_events = env.events().all();
410+
assert_eq!(
411+
token_events,
412+
vec![
413+
&env,
414+
(id.clone(), topics.into_val(&env), data.into_val(&env))
415+
]
416+
);
417+
}
418+
345419
#[test]
346420
fn test_clawback() {
347421
let env = Env::default();

soroban-token-sdk/test_snapshots/tests/events/test_mint.1.json renamed to soroban-token-sdk/test_snapshots/tests/events/test_mint_with_amount_only.1.json

File renamed without changes.
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
{
2+
"generators": {
3+
"address": 2,
4+
"nonce": 0,
5+
"mux_id": 1
6+
},
7+
"auth": [
8+
[],
9+
[]
10+
],
11+
"ledger": {
12+
"protocol_version": 23,
13+
"sequence_number": 0,
14+
"timestamp": 0,
15+
"network_id": "0000000000000000000000000000000000000000000000000000000000000000",
16+
"base_reserve": 0,
17+
"min_persistent_entry_ttl": 4096,
18+
"min_temp_entry_ttl": 16,
19+
"max_entry_ttl": 6312000,
20+
"ledger_entries": [
21+
[
22+
{
23+
"contract_data": {
24+
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
25+
"key": "ledger_key_contract_instance",
26+
"durability": "persistent"
27+
}
28+
},
29+
[
30+
{
31+
"last_modified_ledger_seq": 0,
32+
"data": {
33+
"contract_data": {
34+
"ext": "v0",
35+
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
36+
"key": "ledger_key_contract_instance",
37+
"durability": "persistent",
38+
"val": {
39+
"contract_instance": {
40+
"executable": {
41+
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
42+
},
43+
"storage": null
44+
}
45+
}
46+
}
47+
},
48+
"ext": "v0"
49+
},
50+
4095
51+
]
52+
],
53+
[
54+
{
55+
"contract_code": {
56+
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
57+
}
58+
},
59+
[
60+
{
61+
"last_modified_ledger_seq": 0,
62+
"data": {
63+
"contract_code": {
64+
"ext": "v0",
65+
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
66+
"code": ""
67+
}
68+
},
69+
"ext": "v0"
70+
},
71+
4095
72+
]
73+
]
74+
]
75+
},
76+
"events": [
77+
{
78+
"event": {
79+
"ext": "v0",
80+
"contract_id": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
81+
"type_": "contract",
82+
"body": {
83+
"v0": {
84+
"topics": [
85+
{
86+
"symbol": "mint"
87+
},
88+
{
89+
"address": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6PV"
90+
}
91+
],
92+
"data": {
93+
"map": [
94+
{
95+
"key": {
96+
"symbol": "amount"
97+
},
98+
"val": {
99+
"i128": "123"
100+
}
101+
},
102+
{
103+
"key": {
104+
"symbol": "to_muxed_id"
105+
},
106+
"val": {
107+
"u64": "1"
108+
}
109+
}
110+
]
111+
}
112+
}
113+
}
114+
},
115+
"failed_call": false
116+
}
117+
]
118+
}

0 commit comments

Comments
 (0)