diff --git a/stellar/Cargo.lock b/stellar/Cargo.lock index 26ed325..851ec64 100644 --- a/stellar/Cargo.lock +++ b/stellar/Cargo.lock @@ -687,6 +687,7 @@ name = "governance" version = "0.1.0" dependencies = [ "soroban-sdk", + "wraith-metrics", ] [[package]] @@ -1642,6 +1643,7 @@ name = "stealth-splitter" version = "0.1.0" dependencies = [ "soroban-sdk", + "wraith-metrics", ] [[package]] @@ -1649,6 +1651,7 @@ name = "stealth-vault" version = "0.1.0" dependencies = [ "soroban-sdk", + "wraith-metrics", ] [[package]] @@ -2153,6 +2156,7 @@ dependencies = [ "ed25519-dalek", "proptest", "soroban-sdk", + "wraith-metrics", ] [[package]] diff --git a/stellar/METRICS.md b/stellar/METRICS.md index 51cc1f3..bbd4f84 100644 --- a/stellar/METRICS.md +++ b/stellar/METRICS.md @@ -44,11 +44,26 @@ pub struct WraithMetricEvent { - `batch_send_count` - Number of batch sends - `announce_count` - Number of announcements - `error_count` - Number of errors +- `renew_count` - Number of name renewals (TTL extensions) +- `release_count` - Number of name releases +- `resolve_hit_count` - Number of name resolutions that found an entry +- `resolve_miss_count` - Number of name resolutions that found nothing +- `create_count` - Number of split definitions created +- `fund_count` - Number of split fundings +- `deposit_count` - Number of vault deposits +- `claim_count` - Number of vault claims +- `refund_count` - Number of vault refunds +- `proposal_count` - Number of governance proposals created +- `vote_count` - Number of governance votes cast +- `execution_count` - Number of governance proposals executed ### Gauge/Volume Metrics (absolute values) - `send_volume` - Total volume sent (in token base units) - `batch_size` - Size of a batch operation - `total_transfers` - Total transfers in a batch +- `fund_volume` - Amount distributed by a split funding (in token base units) +- `deposit_volume` - Amount locked by a vault deposit (in token base units) +- `beneficiaries_per_split` - Number of beneficiaries in a split definition ### Timing Metrics (when applicable) - `execution_time_ms` - Execution time in milliseconds @@ -59,9 +74,12 @@ Common dimensions that can be attached to metrics: - `scheme_id` - Stealth address scheme identifier - `token_address` - Token contract address +- `asset_address` - Asset (token) contract address for splitter/vault metrics - `asset_code` - Asset code (if applicable) - `error_code` - Error code (for error metrics) - `contract_version` - Contract version +- `proposal_id` - Governance proposal identifier +- `support` - Vote direction (`true` = for, `false` = against) ## Event Format @@ -102,6 +120,135 @@ env.events().publish( | `batch_send_volume` | After successful batch send | Total amount | `asset_address` | | `batch_size` | After successful batch send | Number of transfers | `asset_address` | +### Wraith Names + +| Metric Name | Trigger | Value | Dimensions | +|-------------|---------|-------|------------| +| `register_count` | After a name is written to storage (covers `register`, `register_on_behalf`, `bulk_register`, and auction `claim_name`) | 1 (increment) | — | +| `renew_count` | After `extend_name_ttl`, and once per `bulk_renew` batch | 1 (increment), or the batch size for `bulk_renew` | — | +| `release_count` | After a name is removed (covers `release` and `release_on_behalf`) | 1 (increment) | — | +| `resolve_hit_count` | After `resolve` finds the name entry | 1 (increment) | — | +| `resolve_miss_count` | When `resolve` does not find the name entry | 1 (increment) | — | + +`bulk_register` emits one `register_count` per name (it calls the same internal +path as `register`), whereas `bulk_renew` emits a single `renew_count` carrying +the batch size as its value. Both aggregate to the same total. + +`resolve` returns `NameNotFound` on a miss. The metric event is published before +the error is returned, so it is captured whenever the enclosing transaction is +applied — for example when `resolve` is invoked as a sub-call by a contract that +handles the error, or during simulation. A top-level `resolve` that fails takes +the whole transaction down with it and, like any other event in a failed +transaction, is not written to the ledger. + +### Stealth Splitter + +| Metric Name | Trigger | Value | Dimensions | +|-------------|---------|-------|------------| +| `create_count` | After a split definition is stored | 1 (increment) | `asset_address` | +| `beneficiaries_per_split` | After a split definition is stored | Number of beneficiaries | `asset_address` | +| `fund_count` | After a successful `fund_split` | 1 (increment) | `asset_address` | +| `fund_volume` | After a successful `fund_split` | Amount distributed | `asset_address` | + +### Stealth Vault + +| Metric Name | Trigger | Value | Dimensions | +|-------------|---------|-------|------------| +| `deposit_count` | After a successful `deposit` | 1 (increment) | `asset_address` | +| `deposit_volume` | After a successful `deposit` | Amount locked | `asset_address` | +| `claim_count` | After a successful `claim` | 1 (increment) | `asset_address` | +| `refund_count` | After a successful `refund` | 1 (increment) | `asset_address` | + +### Governance + +| Metric Name | Trigger | Value | Dimensions | +|-------------|---------|-------|------------| +| `proposal_count` | After a proposal is stored by `propose` | 1 (increment) | `proposal_id` | +| `vote_count` | After a vote is recorded by `vote` | 1 (increment) | `proposal_id`, `support` | +| `execution_count` | After a proposal is executed by `execute` | 1 (increment) | `proposal_id` | + +## Emission Cost + +A metric event is an ordinary contract event, so each `emit_metric` call costs +one `env.events().publish()`. Measured with `cargo bench -p wraith-stellar-bench +--bench gas`, one emission is **+4,164 instructions** and **+144 event bytes** +(with an empty dimension vector); the instruction cost is flat and does not vary +with the metric name or value. + +That is negligible on a write path but material on a cheap read path: + +| Op | Before | After | Delta | +|----|-------:|------:|------:| +| `wraith-names::register` (name_len=3) | 83,942 | 88,106 | +4.96% | +| `wraith-names::register` (name_len=32) | 84,490 | 88,654 | +4.93% | +| `wraith-names::resolve` (hit) | 34,962 | 39,126 | +11.91% | +| `wraith-names::resolve` (miss) | 23,559 | 27,723 | +17.67% | + +`resolve` exceeds the CI bench gate's +5% per-op threshold, so +`stellar/bench/baseline.json` was rotated alongside the wiring. No other benched +op moved: the splitter, vault, and governance write paths are not in the gas +bench, and every other measured op is byte-identical. + +Instrument cheap read paths deliberately — the fixed emission cost dominates +them. + +## Symbol Encoding + +Soroban `Symbol`s used in event topics are limited to 9 characters, so the +contract identifiers and metric names above are abbreviated on-chain. Indexers +must map the wire symbol back to the canonical name from this document. + +| Contract | Wire symbol | +|----------|-------------| +| `stealth-registry` | `st_reg` | +| `stealth-sender` | `st_send` | +| `stealth-batch-sender` | `st_bat_sd` | +| `stealth-announcer` | `st_ann` | +| `wraith-names` | `wr_names` | +| `stealth-splitter` | `st_split` | +| `stealth-vault` | `st_vault` | +| `governance` | `gov` | + +| Metric name | Wire symbol | +|-------------|-------------| +| `register_count` | `reg_cnt` | +| `remove_count` | `rem_cnt` | +| `lookup_count` | `lkp_cnt` | +| `send_count` | `send_cnt` | +| `send_volume` | `send_vol` | +| `batch_send_count` | `bat_send` | +| `batch_send_volume` | `bat_vol` | +| `batch_size` | `bat_size` | +| `error_count` | `err_cnt` | +| `renew_count` | `renew_cnt` | +| `release_count` | `rel_cnt` | +| `resolve_hit_count` | `res_hit` | +| `resolve_miss_count` | `res_miss` | +| `create_count` | `crt_cnt` | +| `fund_count` | `fund_cnt` | +| `fund_volume` | `fund_vol` | +| `beneficiaries_per_split` | `benef_cnt` | +| `deposit_count` | `dep_cnt` | +| `deposit_volume` | `dep_vol` | +| `claim_count` | `clm_cnt` | +| `refund_count` | `rfnd_cnt` | +| `proposal_count` | `prop_cnt` | +| `vote_count` | `vote_cnt` | +| `execution_count` | `exec_cnt` | + +| Dimension name | Wire symbol | +|----------------|-------------| +| `scheme_id` | `scheme_id` | +| `token_address` | `tok_addr` | +| `asset_address` | `ast_addr` | +| `error_code` | `err_code` | +| `proposal_id` | `prop_id` | +| `support` | `support` | + +The canonical constants live in `stellar/wraith-metrics/src/lib.rs` +(`contract_ids`, `metric_names`, `dimension_names`); the indexer's lookup tables +in `stellar/scripts/metrics-indexer/index.js` mirror them. + ## Indexer Implementation A reference indexer implementation is provided in `stellar/scripts/metrics-indexer/` that: diff --git a/stellar/SIZE.md b/stellar/SIZE.md index 74804ca..7f83f1b 100644 --- a/stellar/SIZE.md +++ b/stellar/SIZE.md @@ -48,6 +48,30 @@ source/toolchain mismatch is fixed. Historical contract Previous optimized baseline (bytes) wraith_names 9,755 + +Metric emission delta (wraith_metrics wiring) +Wiring wraith_metrics::emit_metric into wraith-names, stealth-splitter, +stealth-vault, and the governance PoC adds an event publish (and the constant +Symbols it carries) to each write path, so each payload grows. Both columns +below are the optimized payload for the same contract, measured before and +after the metric calls were added; the only difference between them is the +metric emission. + +Contract Before metrics (bytes) After metrics (bytes) Delta Growth +stealth_splitter 9,774 10,720 +946 +9.68% +stealth_vault 9,237 11,117 +1,880 +20.35% +governance 16,589 18,506 +1,917 +11.56% +wraith_names not measurable not measurable — — +All three measurable payloads stay far below the 112,640-byte CI budget; the +largest, governance, is 83.57% below it. + +wraith_names cannot be compiled for wasm32-unknown-unknown at all (see the +note above), so its metric-emission delta cannot be measured on this toolchain. +The failure reproduces identically on the parent commit, so it is unrelated to +the metric wiring. Once the soroban-sdk bump lands and the contract builds, +re-run the command below and fill the row in; the wiring adds five call sites, +so it should land in the same +1 to +2 KB range as the other three. + Reproducing the per-contract delta From this directory, run the same commands used by CI. Record the byte count of each unoptimized WASM before applying the profile/optimizer, then record the @@ -63,4 +87,20 @@ find target/wasm32-unknown-unknown/release -name '*_optimized.wasm' \ -printf '%f %s bytes\n' | sort The optimizer is deliberately run on the release output, as the network deploys the optimized payload rather than the intermediate compiler artifact. CI rejects -any optimized payload over 112,640 bytes. \ No newline at end of file +any optimized payload over 112,640 bytes. + +A workspace-wide wasm32 build fails because integration-tests pulls +soroban-sdk with the testutils feature and Cargo unifies that feature across +the whole build. To measure a single contract, name it explicitly so the +testutils-enabled members stay out of the graph: + +Shell + +cargo build -p stealth-vault -p stealth-splitter -p governance \ + --target wasm32-unknown-unknown --release +for wasm in target/wasm32-unknown-unknown/release/*.wasm; do + stellar contract optimize --wasm "$wasm" +done + +Note that stellar-cli 27.x writes .optimized.wasm where the 22.0.1 CLI +pinned in CI writes _optimized.wasm; match the glob to the CLI in use. \ No newline at end of file diff --git a/stellar/bench/baseline.json b/stellar/bench/baseline.json index 8043825..0313fc1 100644 --- a/stellar/bench/baseline.json +++ b/stellar/bench/baseline.json @@ -1,6 +1,6 @@ { - "generated_at": "1787550854", - "commit": "4dbdc41a99fd2b11e0728d039060a530d7f25392", + "generated_at": "1787666620", + "commit": "d8e51779e61d77153b5c85adbf6ec4ca9c2aa847", "threshold_pct": 5, "results": [ { @@ -163,44 +163,44 @@ "contract": "wraith-names", "function": "register", "params": "name_len=3", - "instructions": 83942, - "mem_bytes": 10503, + "instructions": 88106, + "mem_bytes": 10944, "read_entries": 2, "write_entries": 3, "read_bytes": 104, "write_bytes": 568, - "events_bytes": 204 + "events_bytes": 348 }, { "contract": "wraith-names", "function": "register", "params": "name_len=32", - "instructions": 84490, - "mem_bytes": 10473, + "instructions": 88654, + "mem_bytes": 10914, "read_entries": 2, "write_entries": 3, "read_bytes": 104, "write_bytes": 596, - "events_bytes": 232 + "events_bytes": 376 }, { "contract": "wraith-names", "function": "resolve", "params": "hit", - "instructions": 34962, - "mem_bytes": 3569, + "instructions": 39126, + "mem_bytes": 4010, "read_entries": 2, "write_entries": 0, "read_bytes": 440, "write_bytes": 0, - "events_bytes": 0 + "events_bytes": 144 }, { "contract": "wraith-names", "function": "resolve", "params": "miss", - "instructions": 23559, - "mem_bytes": 2214, + "instructions": 27723, + "mem_bytes": 2655, "read_entries": 2, "write_entries": 0, "read_bytes": 104, diff --git a/stellar/contracts/governance/Cargo.toml b/stellar/contracts/governance/Cargo.toml index 3ece352..73214c8 100644 --- a/stellar/contracts/governance/Cargo.toml +++ b/stellar/contracts/governance/Cargo.toml @@ -9,6 +9,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] soroban-sdk = { workspace = true } +wraith-metrics = { path = "../../wraith-metrics" } [dev-dependencies] soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/stellar/contracts/governance/src/lib.rs b/stellar/contracts/governance/src/lib.rs index b60b86b..24189bd 100644 --- a/stellar/contracts/governance/src/lib.rs +++ b/stellar/contracts/governance/src/lib.rs @@ -19,6 +19,7 @@ use soroban_sdk::{ contract, contracterror, contractimpl, contracttype, symbol_short, token, Address, Bytes, Env, IntoVal, String, Symbol, Val, }; +use wraith_metrics::{contract_ids, dimension_names, emit_metric, metric_names}; // --------------------------------------------------------------------------- // TTL constants (matching the Wraith convention) @@ -260,6 +261,15 @@ impl GovernanceContract { env.events() .publish((symbol_short!("propose"), id), (proposer, description)); + // Emit metric event. + emit_metric( + &env, + contract_ids::GOVERNANCE, + metric_names::PROPOSAL_COUNT, + 1, + soroban_sdk::vec![&env, (dimension_names::PROPOSAL_ID, id.into_val(&env))], + ); + Ok(id) } @@ -345,6 +355,19 @@ impl GovernanceContract { (voter, support, balance), ); + // Emit metric event. + emit_metric( + &env, + contract_ids::GOVERNANCE, + metric_names::VOTE_COUNT, + 1, + soroban_sdk::vec![ + &env, + (dimension_names::PROPOSAL_ID, proposal_id.into_val(&env)), + (dimension_names::SUPPORT, support.into_val(&env)), + ], + ); + Ok(()) } @@ -427,6 +450,18 @@ impl GovernanceContract { env.events() .publish((symbol_short!("execute"), proposal_id), ()); + // Emit metric event. + emit_metric( + &env, + contract_ids::GOVERNANCE, + metric_names::EXECUTION_COUNT, + 1, + soroban_sdk::vec![ + &env, + (dimension_names::PROPOSAL_ID, proposal_id.into_val(&env)) + ], + ); + Ok(()) } @@ -493,7 +528,7 @@ mod test { use super::*; use soroban_sdk::{ contract, contractimpl, symbol_short, - testutils::{Address as _, Ledger}, + testutils::{Address as _, Events, Ledger}, Bytes, Env, String, }; @@ -820,4 +855,113 @@ mod test { let second = gov.try_init(&admin, &token_id, &100, &50, &10); assert_eq!(second, Err(Ok(GovernanceError::AlreadyInitialized))); } + + // ---- metric event shape ------------------------------------------------ + + /// Return the single `("metric", "gov", name)` event in the buffer as + /// `(metric_name, value, dimensions)`. + fn only_metric_event(env: &Env) -> (Symbol, i128, soroban_sdk::Vec<(Symbol, Val)>) { + let metric_topic: Val = symbol_short!("metric").into_val(env); + let mut found = None; + + for (_, topics, data) in env.events().all().iter() { + let first: Option = topics.first(); + if first.map(|t| t.shallow_eq(&metric_topic)) != Some(true) { + continue; + } + + assert!(found.is_none(), "expected exactly one metric event"); + assert_eq!( + topics.len(), + 3, + "metric topics are (metric, contract, name)" + ); + + let emitting: Symbol = topics.get(1).unwrap().into_val(env); + assert_eq!(emitting, contract_ids::GOVERNANCE); + + let metric_name: Symbol = topics.get(2).unwrap().into_val(env); + let (value, dimensions): (i128, soroban_sdk::Vec<(Symbol, Val)>) = data.into_val(env); + found = Some((metric_name, value, dimensions)); + } + + found.expect("no metric event emitted") + } + + #[test] + fn test_propose_emits_proposal_count_metric() { + let (env, gov, _token_id, target_id, _admin) = setup_env(); + + let pid = gov.propose( + &Address::generate(&env), + &target_id, + &symbol_short!("set_value"), + &Bytes::from_slice(&env, b"data"), + &String::from_str(&env, "Metric proposal"), + ); + + let (metric_name, value, dimensions) = only_metric_event(&env); + assert_eq!(metric_name, metric_names::PROPOSAL_COUNT); + assert_eq!(value, 1); + assert_eq!(dimensions.len(), 1); + assert_eq!(dimensions.get(0).unwrap().0, dimension_names::PROPOSAL_ID); + let emitted_id: u32 = dimensions.get(0).unwrap().1.into_val(&env); + assert_eq!(emitted_id, pid); + } + + #[test] + fn test_vote_emits_vote_count_metric() { + let (env, gov, token_id, target_id, _admin) = setup_env(); + let voter = Address::generate(&env); + soroban_sdk::token::StellarAssetClient::new(&env, &token_id).mint(&voter, &200); + + let pid = gov.propose( + &Address::generate(&env), + &target_id, + &symbol_short!("set_value"), + &Bytes::from_slice(&env, b"data"), + &String::from_str(&env, "Metric proposal"), + ); + + gov.vote(&voter, &pid, &false); + + let (metric_name, value, dimensions) = only_metric_event(&env); + assert_eq!(metric_name, metric_names::VOTE_COUNT); + assert_eq!(value, 1); + assert_eq!(dimensions.len(), 2); + assert_eq!(dimensions.get(0).unwrap().0, dimension_names::PROPOSAL_ID); + assert_eq!(dimensions.get(1).unwrap().0, dimension_names::SUPPORT); + let support: bool = dimensions.get(1).unwrap().1.into_val(&env); + assert!(!support); + } + + #[test] + fn test_execute_emits_execution_count_metric() { + let (env, gov, token_id, target_id, _admin) = setup_env(); + + let voter = Address::generate(&env); + soroban_sdk::token::StellarAssetClient::new(&env, &token_id).mint(&voter, &200); + + let pid = gov.propose( + &Address::generate(&env), + &target_id, + &symbol_short!("set_value"), + &Bytes::from_slice(&env, b"metric-exec"), + &String::from_str(&env, "Metric proposal"), + ); + gov.vote(&voter, &pid, &true); + + let proposal = gov.get_proposal(&pid); + env.ledger().with_mut(|li| { + li.sequence_number = proposal.end_ledger + 20; + }); + + gov.execute(&pid); + + let (metric_name, value, dimensions) = only_metric_event(&env); + assert_eq!(metric_name, metric_names::EXECUTION_COUNT); + assert_eq!(value, 1); + assert_eq!(dimensions.len(), 1); + assert_eq!(dimensions.get(0).unwrap().0, dimension_names::PROPOSAL_ID); + } } diff --git a/stellar/contracts/governance/test_snapshots/test/test_execute_emits_execution_count_metric.1.json b/stellar/contracts/governance/test_snapshots/test/test_execute_emits_execution_count_metric.1.json new file mode 100644 index 0000000..bfe93a3 --- /dev/null +++ b/stellar/contracts/governance/test_snapshots/test/test_execute_emits_execution_count_metric.1.json @@ -0,0 +1,899 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 200 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "function_name": "propose", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "symbol": "set_value" + }, + { + "bytes": "6d65747269632d65786563" + }, + { + "string": "Metric proposal" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "function_name": "vote", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "u32": 1 + }, + { + "bool": true + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 70, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Vote" + }, + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Vote" + }, + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "support" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "weight" + }, + "val": { + "i128": { + "hi": 0, + "lo": 200 + } + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextProposalId" + } + ] + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Proposal" + }, + { + "u32": 1 + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "against_votes" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "args" + }, + "val": { + "bytes": "6d65747269632d65786563" + } + }, + { + "key": { + "symbol": "cancelled" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "description" + }, + "val": { + "string": "Metric proposal" + } + }, + { + "key": { + "symbol": "end_ledger" + }, + "val": { + "u32": 50 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "for_votes" + }, + "val": { + "i128": { + "hi": 0, + "lo": 200 + } + } + }, + { + "key": { + "symbol": "function" + }, + "val": { + "symbol": "set_value" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "proposer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "symbol": "start_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "target" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Quorum" + } + ] + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "vec": [ + { + "symbol": "Timelock" + } + ] + }, + "val": { + "u32": 10 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Token" + } + ] + }, + "val": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + } + }, + { + "key": { + "vec": [ + { + "symbol": "VotingPeriod" + } + ] + }, + "val": { + "u32": 50 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "symbol": "value" + }, + "val": { + "bytes": "6d65747269632d65786563" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 200 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 518400 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000004", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "execute" + }, + { + "u32": 1 + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000004", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "gov" + }, + { + "symbol": "exec_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "prop_id" + }, + { + "u32": 1 + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/contracts/governance/test_snapshots/test/test_propose_emits_proposal_count_metric.1.json b/stellar/contracts/governance/test_snapshots/test/test_propose_emits_proposal_count_metric.1.json new file mode 100644 index 0000000..96b0562 --- /dev/null +++ b/stellar/contracts/governance/test_snapshots/test/test_propose_emits_proposal_count_metric.1.json @@ -0,0 +1,637 @@ +{ + "generators": { + "address": 6, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "function_name": "propose", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "symbol": "set_value" + }, + { + "bytes": "64617461" + }, + { + "string": "Metric proposal" + } + ] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextProposalId" + } + ] + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Proposal" + }, + { + "u32": 1 + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "against_votes" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "args" + }, + "val": { + "bytes": "64617461" + } + }, + { + "key": { + "symbol": "cancelled" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "description" + }, + "val": { + "string": "Metric proposal" + } + }, + { + "key": { + "symbol": "end_ledger" + }, + "val": { + "u32": 50 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "for_votes" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "function" + }, + "val": { + "symbol": "set_value" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "proposer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + }, + { + "key": { + "symbol": "start_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "target" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Quorum" + } + ] + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "vec": [ + { + "symbol": "Timelock" + } + ] + }, + "val": { + "u32": 10 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Token" + } + ] + }, + "val": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + } + }, + { + "key": { + "vec": [ + { + "symbol": "VotingPeriod" + } + ] + }, + "val": { + "u32": 50 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 518400 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000004", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "propose" + }, + { + "u32": 1 + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "string": "Metric proposal" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000004", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "gov" + }, + { + "symbol": "prop_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "prop_id" + }, + { + "u32": 1 + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/contracts/governance/test_snapshots/test/test_vote_emits_vote_count_metric.1.json b/stellar/contracts/governance/test_snapshots/test/test_vote_emits_vote_count_metric.1.json new file mode 100644 index 0000000..2fb3fcb --- /dev/null +++ b/stellar/contracts/governance/test_snapshots/test/test_vote_emits_vote_count_metric.1.json @@ -0,0 +1,913 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [], + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 200 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "function_name": "propose", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "symbol": "set_value" + }, + { + "bytes": "64617461" + }, + { + "string": "Metric proposal" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "function_name": "vote", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "u32": 1 + }, + { + "bool": false + } + ] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Vote" + }, + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "vec": [ + { + "symbol": "Vote" + }, + { + "u32": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "support" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "weight" + }, + "val": { + "i128": { + "hi": 0, + "lo": 200 + } + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextProposalId" + } + ] + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Proposal" + }, + { + "u32": 1 + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "against_votes" + }, + "val": { + "i128": { + "hi": 0, + "lo": 200 + } + } + }, + { + "key": { + "symbol": "args" + }, + "val": { + "bytes": "64617461" + } + }, + { + "key": { + "symbol": "cancelled" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "description" + }, + "val": { + "string": "Metric proposal" + } + }, + { + "key": { + "symbol": "end_ledger" + }, + "val": { + "u32": 50 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "for_votes" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "function" + }, + "val": { + "symbol": "set_value" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "proposer" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + }, + { + "key": { + "symbol": "start_ledger" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "target" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Quorum" + } + ] + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "vec": [ + { + "symbol": "Timelock" + } + ] + }, + "val": { + "u32": 10 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Token" + } + ] + }, + "val": { + "address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF" + } + }, + { + "key": { + "vec": [ + { + "symbol": "VotingPeriod" + } + ] + }, + "val": { + "u32": 50 + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 200 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGO6V" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 518400 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000004", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "vote" + }, + { + "u32": 1 + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "bool": false + }, + { + "i128": { + "hi": 0, + "lo": 200 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000004", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "gov" + }, + { + "symbol": "vote_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "prop_id" + }, + { + "u32": 1 + } + ] + }, + { + "vec": [ + { + "symbol": "support" + }, + { + "bool": false + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/scripts/metrics-indexer/README.md b/stellar/scripts/metrics-indexer/README.md index f0890e0..a79a46e 100644 --- a/stellar/scripts/metrics-indexer/README.md +++ b/stellar/scripts/metrics-indexer/README.md @@ -34,8 +34,15 @@ export POLL_INTERVAL_MS=5000 export STEALTH_REGISTRY_ADDRESS="CC..." export STEALTH_SENDER_ADDRESS="CC..." export STEALTH_BATCH_SENDER_ADDRESS="CC..." +export WRAITH_NAMES_ADDRESS="CC..." +export STEALTH_SPLITTER_ADDRESS="CC..." +export STEALTH_VAULT_ADDRESS="CC..." +export GOVERNANCE_ADDRESS="CC..." ``` +Any address left unset is skipped, so the indexer can be pointed at a subset of +the deployment. + ## Usage ### Start the indexer @@ -70,17 +77,39 @@ The indexer exports the following Prometheus metrics: - `wraith_register_count` - Total number of registrations (counter) - `wraith_remove_count` - Total number of removals (counter) +- `wraith_lookup_count` - Total number of meta-address lookups (counter) - `wraith_send_count` - Total number of sends (counter) - `wraith_send_volume` - Total volume sent (gauge) - `wraith_batch_send_count` - Total number of batch sends (counter) - `wraith_batch_send_volume` - Total volume sent in batches (gauge) - `wraith_batch_size` - Size of batch operations (gauge) +- `wraith_error_count` - Total number of contract errors (counter) +- `wraith_renew_count` - Total number of name renewals (counter) +- `wraith_release_count` - Total number of name releases (counter) +- `wraith_resolve_hit_count` - Name resolutions that found an entry (counter) +- `wraith_resolve_miss_count` - Name resolutions that found nothing (counter) +- `wraith_create_count` - Total number of split definitions created (counter) +- `wraith_fund_count` - Total number of split fundings (counter) +- `wraith_fund_volume` - Total volume distributed through splits (gauge) +- `wraith_beneficiaries_per_split` - Beneficiaries in the newest split (gauge) +- `wraith_deposit_count` - Total number of vault deposits (counter) +- `wraith_deposit_volume` - Total volume locked in vault deposits (gauge) +- `wraith_claim_count` - Total number of vault claims (counter) +- `wraith_refund_count` - Total number of vault refunds (counter) +- `wraith_proposal_count` - Total number of governance proposals (counter) +- `wraith_vote_count` - Total number of governance votes cast (counter) +- `wraith_execution_count` - Total number of proposals executed (counter) All metrics include labels for: - `contract` - Contract identifier - `scheme_id` - Stealth address scheme (where applicable) - `token_address` - Token contract address (where applicable) - `asset_address` - Asset contract address (where applicable) +- `proposal_id` - Governance proposal identifier (where applicable) +- `support` - Vote direction, `true`/`false` (governance votes only) + +Dimensions a metric does not carry are reported as `unknown` rather than being +dropped, so a series never silently disappears from a dashboard panel. ## Integration with Prometheus @@ -101,6 +130,10 @@ A demo Grafana dashboard is provided in `grafana-dashboard.json`. Import it into - Send volume trends - Batch operation statistics - Contract activity breakdown +- Name register/renew/release rates and resolution hit ratio +- Splitter create/fund rates, fund volume, and beneficiaries per split +- Vault deposit/claim/refund rates and deposit volume by asset +- Governance proposal, vote, and execution rates To import: @@ -127,10 +160,31 @@ The indexer expects events in the WraithMetricEvent format: **Data:** `(value, dimensions)` -See `stellar/METRICS.md` for the full specification. +Soroban `Symbol`s are capped at 9 characters, so contracts emit abbreviated +topics (`wr_names`, `res_miss`, ...). `index.js` maps them back to the canonical +names via `CONTRACT_SYMBOLS`, `METRIC_SYMBOLS`, and `DIMENSION_SYMBOLS`; keep +those tables in sync with `stellar/wraith-metrics/src/lib.rs`. + +See `stellar/METRICS.md` for the full specification, including the complete +symbol table. ## Testing +### Verify the dashboard against a synthetic event stream + +`synthetic-stream.js` replays a hand-written WraithMetricEvent stream — one +event for every metric in `stellar/METRICS.md` — through the same parser and +aggregator the live indexer uses, then checks that every `wraith_*` metric +referenced by a `grafana-dashboard.json` panel expression has a sample in the +scrape output. A panel that would render blank fails the check. + +```bash +npm run verify:dashboard # exits non-zero if any panel has no data +node synthetic-stream.js --print # also dumps the Prometheus scrape output +``` + +### Against futurenet + To test against futurenet: ```bash diff --git a/stellar/scripts/metrics-indexer/grafana-dashboard.json b/stellar/scripts/metrics-indexer/grafana-dashboard.json index 11df681..2fa9ceb 100644 --- a/stellar/scripts/metrics-indexer/grafana-dashboard.json +++ b/stellar/scripts/metrics-indexer/grafana-dashboard.json @@ -71,7 +71,11 @@ "id": 1, "options": { "legend": { - "calcs": ["mean", "lastNotNull", "max"], + "calcs": [ + "mean", + "lastNotNull", + "max" + ], "displayMode": "table", "placement": "bottom" }, @@ -142,7 +146,11 @@ "id": 2, "options": { "legend": { - "calcs": ["mean", "lastNotNull", "max"], + "calcs": [ + "mean", + "lastNotNull", + "max" + ], "displayMode": "table", "placement": "bottom" }, @@ -213,7 +221,11 @@ "id": 3, "options": { "legend": { - "calcs": ["mean", "lastNotNull", "max"], + "calcs": [ + "mean", + "lastNotNull", + "max" + ], "displayMode": "table", "placement": "bottom" }, @@ -284,7 +296,11 @@ "id": 4, "options": { "legend": { - "calcs": ["mean", "lastNotNull", "max"], + "calcs": [ + "mean", + "lastNotNull", + "max" + ], "displayMode": "table", "placement": "bottom" }, @@ -355,7 +371,11 @@ "id": 5, "options": { "legend": { - "calcs": ["mean", "lastNotNull", "max"], + "calcs": [ + "mean", + "lastNotNull", + "max" + ], "displayMode": "table", "placement": "bottom" }, @@ -426,7 +446,11 @@ "id": 6, "options": { "legend": { - "calcs": ["mean", "lastNotNull", "max"], + "calcs": [ + "mean", + "lastNotNull", + "max" + ], "displayMode": "table", "placement": "bottom" }, @@ -483,7 +507,9 @@ "options": { "orientation": "auto", "reduceOptions": { - "calcs": ["lastNotNull"], + "calcs": [ + "lastNotNull" + ], "fields": "", "values": false }, @@ -529,7 +555,9 @@ "legend": { "displayMode": "table", "placement": "right", - "values": ["value"] + "values": [ + "value" + ] }, "pieType": "pie", "tooltip": { @@ -545,12 +573,902 @@ ], "title": "Registrations by Contract", "type": "piechart" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "tooltip": false, + "viz": false, + "legend": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 32 + }, + "id": 9, + "options": { + "legend": { + "calcs": [ + "mean", + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "expr": "rate(wraith_register_count{contract=\"wraith-names\"}[5m])", + "legendFormat": "register", + "refId": "A" + }, + { + "expr": "rate(wraith_release_count[5m])", + "legendFormat": "release", + "refId": "B" + } + ], + "title": "Name Registrations / Releases", + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "tooltip": false, + "viz": false, + "legend": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 32 + }, + "id": 10, + "options": { + "legend": { + "calcs": [ + "mean", + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "expr": "rate(wraith_renew_count[5m])", + "legendFormat": "renew", + "refId": "A" + } + ], + "title": "Name Renewal Rate", + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "tooltip": false, + "viz": false, + "legend": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 40 + }, + "id": 11, + "options": { + "legend": { + "calcs": [ + "mean", + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "expr": "rate(wraith_resolve_hit_count[5m])", + "legendFormat": "hit", + "refId": "A" + }, + { + "expr": "rate(wraith_resolve_miss_count[5m])", + "legendFormat": "miss", + "refId": "B" + } + ], + "title": "Name Resolution Hits vs Misses", + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "tooltip": false, + "viz": false, + "legend": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 40 + }, + "id": 12, + "options": { + "legend": { + "calcs": [ + "mean", + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "expr": "sum(rate(wraith_resolve_hit_count[5m])) / clamp_min(sum(rate(wraith_resolve_hit_count[5m])) + sum(rate(wraith_resolve_miss_count[5m])), 1)", + "legendFormat": "hit ratio", + "refId": "A" + } + ], + "title": "Name Resolution Hit Ratio", + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "tooltip": false, + "viz": false, + "legend": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 48 + }, + "id": 13, + "options": { + "legend": { + "calcs": [ + "mean", + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "expr": "rate(wraith_create_count[5m])", + "legendFormat": "create - {{asset_address}}", + "refId": "A" + }, + { + "expr": "rate(wraith_fund_count[5m])", + "legendFormat": "fund - {{asset_address}}", + "refId": "B" + } + ], + "title": "Splitter Create / Fund Rate", + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "tooltip": false, + "viz": false, + "legend": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 48 + }, + "id": 14, + "options": { + "legend": { + "calcs": [ + "mean", + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "expr": "wraith_fund_volume", + "legendFormat": "{{contract}} - {{asset_address}}", + "refId": "A" + } + ], + "title": "Splitter Fund Volume", + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 56 + }, + "id": 15, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + }, + "pluginVersion": "8.0.0", + "targets": [ + { + "expr": "wraith_beneficiaries_per_split", + "legendFormat": "{{contract}} - {{asset_address}}", + "refId": "A" + } + ], + "title": "Beneficiaries per Split", + "type": "gauge" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "tooltip": false, + "viz": false, + "legend": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 56 + }, + "id": 16, + "options": { + "legend": { + "calcs": [ + "mean", + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "expr": "rate(wraith_deposit_count[5m])", + "legendFormat": "deposit - {{asset_address}}", + "refId": "A" + }, + { + "expr": "rate(wraith_claim_count[5m])", + "legendFormat": "claim - {{asset_address}}", + "refId": "B" + }, + { + "expr": "rate(wraith_refund_count[5m])", + "legendFormat": "refund - {{asset_address}}", + "refId": "C" + } + ], + "title": "Vault Deposit / Claim / Refund Rate", + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "tooltip": false, + "viz": false, + "legend": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 64 + }, + "id": 17, + "options": { + "legend": { + "calcs": [ + "mean", + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "expr": "wraith_deposit_volume", + "legendFormat": "{{contract}} - {{asset_address}}", + "refId": "A" + } + ], + "title": "Vault Deposit Volume", + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "tooltip": false, + "viz": false, + "legend": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 64 + }, + "id": 18, + "options": { + "legend": { + "calcs": [ + "mean", + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "expr": "rate(wraith_proposal_count[5m])", + "legendFormat": "proposal", + "refId": "A" + }, + { + "expr": "rate(wraith_execution_count[5m])", + "legendFormat": "execution", + "refId": "B" + } + ], + "title": "Governance Proposal / Execution Rate", + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "tooltip": false, + "viz": false, + "legend": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 72 + }, + "id": 19, + "options": { + "legend": { + "calcs": [ + "mean", + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "expr": "sum by (support) (rate(wraith_vote_count[5m]))", + "legendFormat": "support={{support}}", + "refId": "A" + } + ], + "title": "Governance Votes by Direction", + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "tooltip": false, + "viz": false, + "legend": false + } + } + }, + "mappings": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 72 + }, + "id": 20, + "options": { + "legend": { + "displayMode": "table", + "placement": "right", + "values": [ + "value" + ] + }, + "pieType": "pie", + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "expr": "sum by (asset_address) (wraith_deposit_volume)", + "legendFormat": "{{asset_address}}", + "refId": "A" + } + ], + "title": "Vault Deposit Volume by Asset", + "type": "piechart" } ], "refresh": "5s", "schemaVersion": 27, "style": "dark", - "tags": ["wraith", "stellar", "metrics"], + "tags": [ + "wraith", + "stellar", + "metrics" + ], "templating": { "list": [] }, @@ -562,5 +1480,5 @@ "timezone": "", "title": "Wraith Protocol Metrics", "uid": "wraith-metrics", - "version": 1 + "version": 2 } diff --git a/stellar/scripts/metrics-indexer/index.js b/stellar/scripts/metrics-indexer/index.js index 983c970..dc4697b 100644 --- a/stellar/scripts/metrics-indexer/index.js +++ b/stellar/scripts/metrics-indexer/index.js @@ -1,10 +1,11 @@ -import { Server, Api } from '@stellar/stellar-sdk'; +import { rpc } from '@stellar/stellar-sdk'; import express from 'express'; import { Registry, Counter, Gauge } from 'prom-client'; // Configuration const RPC_URL = process.env.RPC_URL || 'https://futurenet.sorobanrpc.com'; -const NETWORK_PASSPHRASE = process.env.NETWORK_PASSPHRASE || 'Test SDF Future Network ; October 2022'; +const NETWORK_PASSPHRASE = + process.env.NETWORK_PASSPHRASE || 'Test SDF Future Network ; October 2022'; const PORT = process.env.PORT || 9090; const POLL_INTERVAL_MS = process.env.POLL_INTERVAL_MS || 5000; @@ -13,70 +14,128 @@ const CONTRACTS = { stealthRegistry: process.env.STEALTH_REGISTRY_ADDRESS, stealthSender: process.env.STEALTH_SENDER_ADDRESS, stealthBatchSender: process.env.STEALTH_BATCH_SENDER_ADDRESS, + wraithNames: process.env.WRAITH_NAMES_ADDRESS, + stealthSplitter: process.env.STEALTH_SPLITTER_ADDRESS, + stealthVault: process.env.STEALTH_VAULT_ADDRESS, + governance: process.env.GOVERNANCE_ADDRESS, +}; + +// Soroban Symbols are capped at 9 characters, so contracts emit abbreviated +// topics. These tables map the on-chain wire symbols back to the canonical +// names documented in stellar/METRICS.md. Keep them in sync with +// stellar/wraith-metrics/src/lib.rs. +const CONTRACT_SYMBOLS = { + st_reg: 'stealth-registry', + st_send: 'stealth-sender', + st_bat_sd: 'stealth-batch-sender', + st_ann: 'stealth-announcer', + wr_names: 'wraith-names', + st_split: 'stealth-splitter', + st_vault: 'stealth-vault', + gov: 'governance', +}; + +const METRIC_SYMBOLS = { + reg_cnt: 'register_count', + rem_cnt: 'remove_count', + lkp_cnt: 'lookup_count', + send_cnt: 'send_count', + send_vol: 'send_volume', + bat_send: 'batch_send_count', + bat_vol: 'batch_send_volume', + bat_size: 'batch_size', + err_cnt: 'error_count', + renew_cnt: 'renew_count', + rel_cnt: 'release_count', + res_hit: 'resolve_hit_count', + res_miss: 'resolve_miss_count', + crt_cnt: 'create_count', + fund_cnt: 'fund_count', + fund_vol: 'fund_volume', + benef_cnt: 'beneficiaries_per_split', + dep_cnt: 'deposit_count', + dep_vol: 'deposit_volume', + clm_cnt: 'claim_count', + rfnd_cnt: 'refund_count', + prop_cnt: 'proposal_count', + vote_cnt: 'vote_count', + exec_cnt: 'execution_count', +}; + +const DIMENSION_SYMBOLS = { + scheme_id: 'scheme_id', + tok_addr: 'token_address', + ast_addr: 'asset_address', + err_code: 'error_code', + prop_id: 'proposal_id', + support: 'support', }; // Initialize Stellar RPC server -const server = new Server(RPC_URL); +const server = new rpc.Server(RPC_URL); // Initialize Prometheus registry -const register = new Registry(); - -// Define Prometheus metrics -const metrics = { - registerCount: new Counter({ - name: 'wraith_register_count', - help: 'Total number of registrations', - labelNames: ['contract', 'scheme_id'], - registers: [register], - }), - removeCount: new Counter({ - name: 'wraith_remove_count', - help: 'Total number of removals', - labelNames: ['contract', 'scheme_id'], - registers: [register], - }), - sendCount: new Counter({ - name: 'wraith_send_count', - help: 'Total number of sends', - labelNames: ['contract', 'scheme_id', 'token_address'], - registers: [register], - }), - sendVolume: new Gauge({ - name: 'wraith_send_volume', - help: 'Total volume sent', - labelNames: ['contract', 'scheme_id', 'token_address'], - registers: [register], - }), - batchSendCount: new Counter({ - name: 'wraith_batch_send_count', - help: 'Total number of batch sends', - labelNames: ['contract', 'scheme_id', 'token_address', 'asset_address'], - registers: [register], - }), - batchSendVolume: new Gauge({ - name: 'wraith_batch_send_volume', - help: 'Total volume sent in batches', - labelNames: ['contract', 'scheme_id', 'token_address', 'asset_address'], - registers: [register], - }), - batchSize: new Gauge({ - name: 'wraith_batch_size', - help: 'Size of batch operations', - labelNames: ['contract', 'scheme_id', 'token_address', 'asset_address'], - registers: [register], - }), +export const register = new Registry(); + +// Metric specifications. +// +// `kind` selects the aggregation: +// counter - monotonic total; each event adds its value +// sum_gauge - running total exposed as a gauge (volumes) +// gauge - last observed value (point-in-time sizes) +const METRIC_SPECS = { + register_count: { kind: 'counter', name: 'wraith_register_count', help: 'Total number of registrations', labels: ['scheme_id'] }, + remove_count: { kind: 'counter', name: 'wraith_remove_count', help: 'Total number of removals', labels: ['scheme_id'] }, + lookup_count: { kind: 'counter', name: 'wraith_lookup_count', help: 'Total number of meta-address lookups', labels: ['scheme_id'] }, + send_count: { kind: 'counter', name: 'wraith_send_count', help: 'Total number of sends', labels: ['scheme_id', 'token_address'] }, + send_volume: { kind: 'sum_gauge', name: 'wraith_send_volume', help: 'Total volume sent', labels: ['scheme_id', 'token_address'] }, + batch_send_count: { kind: 'counter', name: 'wraith_batch_send_count', help: 'Total number of batch sends', labels: ['scheme_id', 'token_address', 'asset_address'] }, + batch_send_volume: { kind: 'sum_gauge', name: 'wraith_batch_send_volume', help: 'Total volume sent in batches', labels: ['scheme_id', 'token_address', 'asset_address'] }, + batch_size: { kind: 'gauge', name: 'wraith_batch_size', help: 'Size of batch operations', labels: ['scheme_id', 'token_address', 'asset_address'] }, + error_count: { kind: 'counter', name: 'wraith_error_count', help: 'Total number of contract errors', labels: ['error_code'] }, + + // wraith-names + renew_count: { kind: 'counter', name: 'wraith_renew_count', help: 'Total number of name renewals', labels: [] }, + release_count: { kind: 'counter', name: 'wraith_release_count', help: 'Total number of name releases', labels: [] }, + resolve_hit_count: { kind: 'counter', name: 'wraith_resolve_hit_count', help: 'Total number of name resolutions that found an entry', labels: [] }, + resolve_miss_count: { kind: 'counter', name: 'wraith_resolve_miss_count', help: 'Total number of name resolutions that found nothing', labels: [] }, + + // stealth-splitter + create_count: { kind: 'counter', name: 'wraith_create_count', help: 'Total number of split definitions created', labels: ['asset_address'] }, + fund_count: { kind: 'counter', name: 'wraith_fund_count', help: 'Total number of split fundings', labels: ['asset_address'] }, + fund_volume: { kind: 'sum_gauge', name: 'wraith_fund_volume', help: 'Total volume distributed through splits', labels: ['asset_address'] }, + beneficiaries_per_split: { kind: 'gauge', name: 'wraith_beneficiaries_per_split', help: 'Beneficiaries in the most recently created split', labels: ['asset_address'] }, + + // stealth-vault + deposit_count: { kind: 'counter', name: 'wraith_deposit_count', help: 'Total number of vault deposits', labels: ['asset_address'] }, + deposit_volume: { kind: 'sum_gauge', name: 'wraith_deposit_volume', help: 'Total volume locked in vault deposits', labels: ['asset_address'] }, + claim_count: { kind: 'counter', name: 'wraith_claim_count', help: 'Total number of vault claims', labels: ['asset_address'] }, + refund_count: { kind: 'counter', name: 'wraith_refund_count', help: 'Total number of vault refunds', labels: ['asset_address'] }, + + // governance + proposal_count: { kind: 'counter', name: 'wraith_proposal_count', help: 'Total number of governance proposals created', labels: ['proposal_id'] }, + vote_count: { kind: 'counter', name: 'wraith_vote_count', help: 'Total number of governance votes cast', labels: ['proposal_id', 'support'] }, + execution_count: { kind: 'counter', name: 'wraith_execution_count', help: 'Total number of governance proposals executed', labels: ['proposal_id'] }, }; -// In-memory metric storage -const metricStore = { - registerCount: new Map(), - removeCount: new Map(), - sendCount: new Map(), - sendVolume: new Map(), - batchSendCount: new Map(), - batchSendVolume: new Map(), - batchSize: new Map(), -}; +// Instantiate one Prometheus collector per spec. Every collector carries a +// `contract` label so a single panel can break down by emitting contract. +const metrics = {}; +for (const [metricName, spec] of Object.entries(METRIC_SPECS)) { + const options = { + name: spec.name, + help: spec.help, + labelNames: ['contract', ...spec.labels], + registers: [register], + }; + metrics[metricName] = spec.kind === 'counter' ? new Counter(options) : new Gauge(options); +} + +// In-memory metric storage: metricName -> Map(seriesKey -> running total) +const metricStore = {}; +for (const metricName of Object.keys(METRIC_SPECS)) { + metricStore[metricName] = new Map(); +} // Generate key for metric storage function getMetricKey(contract, dimensions) { @@ -87,19 +146,32 @@ function getMetricKey(contract, dimensions) { return `${contract}:${dimString}`; } -// Parse metric event from Soroban event -function parseMetricEvent(event) { +// Build the Prometheus label set for a metric, filling absent dimensions with +// 'unknown' so a series never silently disappears from a dashboard panel. +function buildLabels(spec, contract, dimensions) { + const labels = { contract }; + for (const label of spec.labels) { + labels[label] = dimensions[label] !== undefined ? String(dimensions[label]) : 'unknown'; + } + return labels; +} + +// Parse metric event from Soroban event. +// +// Topics and values are expected to have already been converted to native JS +// (see `scValToNative` in @stellar/stellar-sdk) by the transport layer. +export function parseMetricEvent(event) { try { const topic = event.topic; const value = event.value; // Check if this is a metric event (topic[0] should be "metric") - if (topic.length < 3 || topic[0] !== 'metric') { + if (!Array.isArray(topic) || topic.length < 3 || topic[0] !== 'metric') { return null; } - const contract = topic[1]; - const metricName = topic[2]; + const contract = CONTRACT_SYMBOLS[topic[1]] || topic[1]; + const metricName = METRIC_SYMBOLS[topic[2]] || topic[2]; // Parse dimensions from value const dimensions = {}; @@ -107,12 +179,12 @@ function parseMetricEvent(event) { const dimArray = value[1]; if (Array.isArray(dimArray)) { for (const [key, val] of dimArray) { - dimensions[key] = val; + dimensions[DIMENSION_SYMBOLS[key] || key] = val; } } } - const metricValue = value[0]; + const metricValue = Number(value[0]); return { contract, @@ -127,83 +199,38 @@ function parseMetricEvent(event) { } // Update metric storage -function updateMetric(metricEvent) { +export function updateMetric(metricEvent) { const { contract, metricName, value, dimensions } = metricEvent; - const key = getMetricKey(contract, dimensions); - - switch (metricName) { - case 'register_count': - const currentRegCount = metricStore.registerCount.get(key) || 0; - metricStore.registerCount.set(key, currentRegCount + value); - metrics.registerCount.inc({ - contract, - scheme_id: dimensions.scheme_id || 'unknown', - }); - break; - - case 'remove_count': - const currentRemoveCount = metricStore.removeCount.get(key) || 0; - metricStore.removeCount.set(key, currentRemoveCount + value); - metrics.removeCount.inc({ - contract, - scheme_id: dimensions.scheme_id || 'unknown', - }); - break; + const spec = METRIC_SPECS[metricName]; - case 'send_count': - const currentSendCount = metricStore.sendCount.get(key) || 0; - metricStore.sendCount.set(key, currentSendCount + value); - metrics.sendCount.inc({ - contract, - scheme_id: dimensions.scheme_id || 'unknown', - token_address: dimensions.token_address || 'unknown', - }); - break; + if (!spec) { + console.log(`Unknown metric name: ${metricName}`); + return; + } - case 'send_volume': - const currentSendVolume = metricStore.sendVolume.get(key) || 0; - metricStore.sendVolume.set(key, currentSendVolume + value); - metrics.sendVolume.set({ - contract, - scheme_id: dimensions.scheme_id || 'unknown', - token_address: dimensions.token_address || 'unknown', - }, currentSendVolume + value); - break; + const key = getMetricKey(contract, dimensions); + const labels = buildLabels(spec, contract, dimensions); - case 'batch_send_count': - const currentBatchCount = metricStore.batchSendCount.get(key) || 0; - metricStore.batchSendCount.set(key, currentBatchCount + value); - metrics.batchSendCount.inc({ - contract, - scheme_id: dimensions.scheme_id || 'unknown', - token_address: dimensions.token_address || 'unknown', - asset_address: dimensions.asset_address || 'unknown', - }); + switch (spec.kind) { + case 'counter': { + const total = (metricStore[metricName].get(key) || 0) + value; + metricStore[metricName].set(key, total); + metrics[metricName].inc(labels, value); break; + } - case 'batch_send_volume': - const currentBatchVolume = metricStore.batchSendVolume.get(key) || 0; - metricStore.batchSendVolume.set(key, currentBatchVolume + value); - metrics.batchSendVolume.set({ - contract, - scheme_id: dimensions.scheme_id || 'unknown', - token_address: dimensions.token_address || 'unknown', - asset_address: dimensions.asset_address || 'unknown', - }, currentBatchVolume + value); + case 'sum_gauge': { + const total = (metricStore[metricName].get(key) || 0) + value; + metricStore[metricName].set(key, total); + metrics[metricName].set(labels, total); break; + } - case 'batch_size': - metricStore.batchSize.set(key, value); - metrics.batchSize.set({ - contract, - scheme_id: dimensions.scheme_id || 'unknown', - token_address: dimensions.token_address || 'unknown', - asset_address: dimensions.asset_address || 'unknown', - }, value); + case 'gauge': { + metricStore[metricName].set(key, value); + metrics[metricName].set(labels, value); break; - - default: - console.log(`Unknown metric name: ${metricName}`); + } } } @@ -255,43 +282,50 @@ async function processEvents() { console.log('Event processing complete'); } -// Start Express server for Prometheus metrics -const app = express(); +export function start() { + // Start Express server for Prometheus metrics + const app = express(); -app.get('/metrics', async (req, res) => { - try { - res.set('Content-Type', register.contentType); - res.end(await register.metrics()); - } catch (error) { - res.status(500).end(error.toString()); - } -}); - -app.get('/health', (req, res) => { - res.json({ status: 'healthy' }); -}); - -// Start the server -app.listen(PORT, () => { - console.log(`Metrics indexer listening on port ${PORT}`); - console.log(`Prometheus metrics available at http://localhost:${PORT}/metrics`); - console.log(`RPC URL: ${RPC_URL}`); - console.log(`Network: ${NETWORK_PASSPHRASE}`); - - // Initial event processing - processEvents(); - - // Poll for new events - setInterval(processEvents, POLL_INTERVAL_MS); -}); - -// Graceful shutdown -process.on('SIGTERM', () => { - console.log('SIGTERM received, shutting down gracefully'); - process.exit(0); -}); - -process.on('SIGINT', () => { - console.log('SIGINT received, shutting down gracefully'); - process.exit(0); -}); + app.get('/metrics', async (req, res) => { + try { + res.set('Content-Type', register.contentType); + res.end(await register.metrics()); + } catch (error) { + res.status(500).end(error.toString()); + } + }); + + app.get('/health', (req, res) => { + res.json({ status: 'healthy' }); + }); + + app.listen(PORT, () => { + console.log(`Metrics indexer listening on port ${PORT}`); + console.log(`Prometheus metrics available at http://localhost:${PORT}/metrics`); + console.log(`RPC URL: ${RPC_URL}`); + console.log(`Network: ${NETWORK_PASSPHRASE}`); + + // Initial event processing + processEvents(); + + // Poll for new events + setInterval(processEvents, POLL_INTERVAL_MS); + }); + + // Graceful shutdown + process.on('SIGTERM', () => { + console.log('SIGTERM received, shutting down gracefully'); + process.exit(0); + }); + + process.on('SIGINT', () => { + console.log('SIGINT received, shutting down gracefully'); + process.exit(0); + }); +} + +// Only start the HTTP server when run directly, so the parser and aggregator +// can be imported by verification scripts (see synthetic-stream.js). +if (process.argv[1] && import.meta.url === new URL(`file://${process.argv[1]}`).href) { + start(); +} diff --git a/stellar/scripts/metrics-indexer/package.json b/stellar/scripts/metrics-indexer/package.json index 9837284..cfdca44 100644 --- a/stellar/scripts/metrics-indexer/package.json +++ b/stellar/scripts/metrics-indexer/package.json @@ -6,7 +6,8 @@ "type": "module", "scripts": { "start": "node index.js", - "dev": "node --watch index.js" + "dev": "node --watch index.js", + "verify:dashboard": "node synthetic-stream.js" }, "dependencies": { "@stellar/stellar-sdk": "^12.0.0", diff --git a/stellar/scripts/metrics-indexer/synthetic-stream.js b/stellar/scripts/metrics-indexer/synthetic-stream.js new file mode 100644 index 0000000..9ce070e --- /dev/null +++ b/stellar/scripts/metrics-indexer/synthetic-stream.js @@ -0,0 +1,163 @@ +#!/usr/bin/env node +// +// Feeds a synthetic WraithMetricEvent stream through the indexer's parser and +// aggregator, then checks that every Prometheus metric referenced by +// grafana-dashboard.json is present in the exported scrape output. +// +// This is the offline substitute for pointing Grafana at a live network: if a +// panel references a metric no contract emits (or that the indexer drops on the +// floor), the panel renders blank and this script fails. +// +// node synthetic-stream.js # verify +// node synthetic-stream.js --print # verify and dump the scrape output + +import { readFileSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import { parseMetricEvent, updateMetric, register } from './index.js'; + +const HERE = dirname(fileURLToPath(import.meta.url)); +const DASHBOARD_PATH = join(HERE, 'grafana-dashboard.json'); + +const ASSET_A = 'CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC'; +const ASSET_B = 'CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA'; + +// Events as the contracts emit them: abbreviated wire symbols in the topic, +// (value, dimensions) in the data. Every metric in stellar/METRICS.md appears +// at least once so the dashboard has something to draw for each panel. +const SYNTHETIC_EVENTS = [ + // stealth-registry + ['st_reg', 'reg_cnt', 1, [['scheme_id', 1]]], + ['st_reg', 'reg_cnt', 1, [['scheme_id', 1]]], + ['st_reg', 'rem_cnt', 1, [['scheme_id', 1]]], + ['st_reg', 'lkp_cnt', 1, [['scheme_id', 1]]], + + // stealth-sender + ['st_send', 'send_cnt', 1, [['scheme_id', 1], ['tok_addr', ASSET_A]]], + ['st_send', 'send_vol', 5_000_000, [['scheme_id', 1], ['tok_addr', ASSET_A]]], + ['st_send', 'bat_send', 1, [['scheme_id', 1], ['tok_addr', ASSET_A]]], + ['st_send', 'bat_vol', 12_000_000, [['scheme_id', 1], ['tok_addr', ASSET_A]]], + ['st_send', 'bat_size', 4, [['scheme_id', 1], ['tok_addr', ASSET_A]]], + + // stealth-batch-sender + ['st_bat_sd', 'bat_send', 1, [['ast_addr', ASSET_B]]], + ['st_bat_sd', 'bat_vol', 3_000_000, [['ast_addr', ASSET_B]]], + ['st_bat_sd', 'bat_size', 12, [['ast_addr', ASSET_B]]], + + // wraith-names + ['wr_names', 'reg_cnt', 1, []], + ['wr_names', 'reg_cnt', 1, []], + ['wr_names', 'reg_cnt', 1, []], + ['wr_names', 'renew_cnt', 1, []], + ['wr_names', 'renew_cnt', 5, []], // bulk_renew carries the batch size + ['wr_names', 'rel_cnt', 1, []], + ['wr_names', 'res_hit', 1, []], + ['wr_names', 'res_hit', 1, []], + ['wr_names', 'res_miss', 1, []], + + // stealth-splitter + ['st_split', 'crt_cnt', 1, [['ast_addr', ASSET_A]]], + ['st_split', 'benef_cnt', 3, [['ast_addr', ASSET_A]]], + ['st_split', 'fund_cnt', 1, [['ast_addr', ASSET_A]]], + ['st_split', 'fund_vol', 9_000_000, [['ast_addr', ASSET_A]]], + + // stealth-vault + ['st_vault', 'dep_cnt', 1, [['ast_addr', ASSET_A]]], + ['st_vault', 'dep_vol', 1_000_000, [['ast_addr', ASSET_A]]], + ['st_vault', 'dep_cnt', 1, [['ast_addr', ASSET_B]]], + ['st_vault', 'dep_vol', 2_500_000, [['ast_addr', ASSET_B]]], + ['st_vault', 'clm_cnt', 1, [['ast_addr', ASSET_A]]], + ['st_vault', 'rfnd_cnt', 1, [['ast_addr', ASSET_B]]], + + // governance + ['gov', 'prop_cnt', 1, [['prop_id', 0]]], + ['gov', 'vote_cnt', 1, [['prop_id', 0], ['support', true]]], + ['gov', 'vote_cnt', 1, [['prop_id', 0], ['support', false]]], + ['gov', 'exec_cnt', 1, [['prop_id', 0]]], +].map(([contract, metricName, value, dimensions]) => ({ + topic: ['metric', contract, metricName], + value: [value, dimensions], +})); + +// Pull every `wraith_*` metric name out of the dashboard's panel expressions. +function dashboardMetricNames() { + const dashboard = JSON.parse(readFileSync(DASHBOARD_PATH, 'utf8')); + const referenced = new Map(); + + for (const panel of dashboard.panels ?? []) { + for (const target of panel.targets ?? []) { + for (const name of target.expr.match(/wraith_[a-z0-9_]+/g) ?? []) { + if (!referenced.has(name)) { + referenced.set(name, []); + } + referenced.get(name).push(panel.title); + } + } + } + + return referenced; +} + +// A metric is only "rendered" if the scrape carries a sample for it, not just a +// HELP/TYPE header — prom-client emits the header for a labelled collector that +// has never been observed. +function sampledMetricNames(scrape) { + const sampled = new Set(); + for (const line of scrape.split('\n')) { + if (line.startsWith('#') || line.trim() === '') { + continue; + } + const name = line.split(/[{ ]/)[0]; + if (name) { + sampled.add(name); + } + } + return sampled; +} + +async function main() { + let parsed = 0; + for (const event of SYNTHETIC_EVENTS) { + const metricEvent = parseMetricEvent(event); + if (!metricEvent) { + console.error(`FAIL: could not parse synthetic event ${JSON.stringify(event.topic)}`); + process.exit(1); + } + updateMetric(metricEvent); + parsed += 1; + } + + const scrape = await register.metrics(); + const sampled = sampledMetricNames(scrape); + const referenced = dashboardMetricNames(); + + const missing = []; + for (const [name, panels] of referenced) { + if (!sampled.has(name)) { + missing.push(`${name} (panels: ${[...new Set(panels)].join(', ')})`); + } + } + + if (process.argv.includes('--print')) { + console.log(scrape); + } + + console.log(`Replayed ${parsed} synthetic metric events.`); + console.log(`Dashboard references ${referenced.size} distinct wraith_* metrics.`); + + if (missing.length > 0) { + console.error('FAIL: dashboard panels reference metrics with no samples:'); + for (const entry of missing) { + console.error(` - ${entry}`); + } + process.exit(1); + } + + console.log('OK: every dashboard panel has data to render.'); +} + +main().catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/stellar/stealth-splitter/Cargo.toml b/stellar/stealth-splitter/Cargo.toml index 5a189de..97e5e47 100644 --- a/stellar/stealth-splitter/Cargo.toml +++ b/stellar/stealth-splitter/Cargo.toml @@ -8,6 +8,7 @@ crate-type = ["cdylib"] [dependencies] soroban-sdk = { workspace = true } +wraith-metrics = { path = "../wraith-metrics" } [dev-dependencies] soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/stellar/stealth-splitter/src/lib.rs b/stellar/stealth-splitter/src/lib.rs index 09c30ca..93f6f65 100644 --- a/stellar/stealth-splitter/src/lib.rs +++ b/stellar/stealth-splitter/src/lib.rs @@ -4,6 +4,7 @@ use soroban_sdk::{ contract, contracterror, contractimpl, contracttype, token, Address, Bytes, BytesN, Env, IntoVal, Symbol, Vec, }; +use wraith_metrics::{contract_ids, dimension_names, emit_metric, metric_names}; /// Storage keys. #[contracttype] @@ -196,6 +197,29 @@ impl StealthSplitterContract { beneficiaries.len(), ); + // Emit metric events. + let dimensions = soroban_sdk::vec![ + &env, + ( + dimension_names::ASSET_ADDRESS, + definition.asset.into_val(&env) + ) + ]; + emit_metric( + &env, + contract_ids::STEALTH_SPLITTER, + metric_names::CREATE_COUNT, + 1, + dimensions.clone(), + ); + emit_metric( + &env, + contract_ids::STEALTH_SPLITTER, + metric_names::BENEFICIARIES_PER_SPLIT, + beneficiaries.len() as i128, + dimensions, + ); + Ok(split_id) } @@ -310,6 +334,29 @@ impl StealthSplitterContract { env.events() .publish((Symbol::short("fund"), split_id), amount); + // Emit metric events. + let dimensions = soroban_sdk::vec![ + &env, + ( + dimension_names::ASSET_ADDRESS, + definition.asset.into_val(&env) + ) + ]; + emit_metric( + &env, + contract_ids::STEALTH_SPLITTER, + metric_names::FUND_COUNT, + 1, + dimensions.clone(), + ); + emit_metric( + &env, + contract_ids::STEALTH_SPLITTER, + metric_names::FUND_VOLUME, + amount, + dimensions, + ); + Ok(()) } @@ -855,4 +902,144 @@ mod test { // - Savings: Reduced tx overhead, atomic batching // - For N=25: ~25x reduction in transaction count // - Resource cost: ~2-3 KB storage per split definition (retained) + + // ============ METRIC EVENT SHAPE ============ + + #[contract] + pub struct MockAnnouncer; + + #[contractimpl] + impl MockAnnouncer { + pub fn announce( + _env: Env, + _scheme_id: u32, + _stealth_address: Address, + _ephemeral_pub_key: BytesN<32>, + _metadata: Bytes, + ) { + } + } + + /// Collect the `("metric", contract, name)` events currently in the buffer + /// as `(metric_name, value, asset_address_dimension)` triples. + fn metric_events(env: &Env) -> soroban_sdk::Vec<(Symbol, i128, Address)> { + let metric_topic: soroban_sdk::Val = symbol_short!("metric").into_val(env); + let mut collected = soroban_sdk::Vec::new(env); + + for (_, topics, data) in env.events().all().iter() { + let first: Option = topics.first(); + if first.map(|t| t.shallow_eq(&metric_topic)) != Some(true) { + continue; + } + + assert_eq!( + topics.len(), + 3, + "metric topics are (metric, contract, name)" + ); + let emitting: Symbol = topics.get(1).unwrap().into_val(env); + assert_eq!(emitting, contract_ids::STEALTH_SPLITTER); + + let metric_name: Symbol = topics.get(2).unwrap().into_val(env); + let (value, dimensions): (i128, soroban_sdk::Vec<(Symbol, soroban_sdk::Val)>) = + data.into_val(env); + + assert_eq!(dimensions.len(), 1, "expected the asset_address dimension"); + let (dimension_name, dimension_value) = dimensions.get(0).unwrap(); + assert_eq!(dimension_name, dimension_names::ASSET_ADDRESS); + let asset: Address = dimension_value.into_val(env); + + collected.push_back((metric_name, value, asset)); + } + + collected + } + + #[test] + fn test_create_split_emits_metric_events() { + let (env, contract_id, _announcer) = setup_env(); + let client = StealthSplitterContractClient::new(&env, &contract_id); + + let creator = Address::generate(&env); + let asset = Address::generate(&env); + let salt = Bytes::from_slice(&env, b"metric-salt"); + + let mut beneficiaries = vec![&env]; + beneficiaries.push_back(create_test_beneficiary(&env, 1)); + beneficiaries.push_back(create_test_beneficiary(&env, 2)); + beneficiaries.push_back(create_test_beneficiary(&env, 3)); + + client.create_split(&creator, &beneficiaries, &asset, &salt); + + let metrics = metric_events(&env); + assert_eq!( + metrics, + vec![ + &env, + (metric_names::CREATE_COUNT, 1i128, asset.clone()), + (metric_names::BENEFICIARIES_PER_SPLIT, 3i128, asset), + ] + ); + } + + #[test] + fn test_fund_split_emits_metric_events() { + let env = Env::default(); + env.mock_all_auths(); + + let announcer_id = env.register(MockAnnouncer, ()); + let contract_id = env.register(StealthSplitterContract, ()); + let client = StealthSplitterContractClient::new(&env, &contract_id); + client.init(&announcer_id); + + let token_admin = Address::generate(&env); + let asset = env + .register_stellar_asset_contract_v2(token_admin) + .address(); + let funder = Address::generate(&env); + token::StellarAssetClient::new(&env, &asset).mint(&funder, &10_000); + + let mut beneficiaries = vec![&env]; + beneficiaries.push_back(create_test_beneficiary(&env, 1)); + beneficiaries.push_back(create_test_beneficiary(&env, 2)); + + let split_id = client.create_split( + &funder, + &beneficiaries, + &asset, + &Bytes::from_slice(&env, b"fund-metric-salt"), + ); + + let stealth_addresses = vec![&env, Address::generate(&env), Address::generate(&env)]; + let ephemeral_pub_keys = vec![ + &env, + BytesN::from_array(&env, &[1u8; 32]), + BytesN::from_array(&env, &[2u8; 32]), + ]; + let metadatas = vec![ + &env, + Bytes::from_slice(&env, &[1u8]), + Bytes::from_slice(&env, &[2u8]), + ]; + + client.fund_split( + &funder, + &split_id, + &6_000, + &1u32, + &stealth_addresses, + &ephemeral_pub_keys, + &metadatas, + ); + + let metrics = metric_events(&env); + assert_eq!( + metrics, + vec![ + &env, + (metric_names::FUND_COUNT, 1i128, asset.clone()), + (metric_names::FUND_VOLUME, 6_000i128, asset), + ] + ); + } } diff --git a/stellar/stealth-splitter/test_snapshots/test/test_create_split_basic.1.json b/stellar/stealth-splitter/test_snapshots/test/test_create_split_basic.1.json index 2e111fd..75d39ff 100644 --- a/stellar/stealth-splitter/test_snapshots/test/test_create_split_basic.1.json +++ b/stellar/stealth-splitter/test_snapshots/test/test_create_split_basic.1.json @@ -329,6 +329,100 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "crt_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "benef_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 2 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/stealth-splitter/test_snapshots/test/test_create_split_deterministic_id.1.json b/stellar/stealth-splitter/test_snapshots/test/test_create_split_deterministic_id.1.json index 25b541e..1c1c414 100644 --- a/stellar/stealth-splitter/test_snapshots/test/test_create_split_deterministic_id.1.json +++ b/stellar/stealth-splitter/test_snapshots/test/test_create_split_deterministic_id.1.json @@ -437,6 +437,100 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "crt_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "benef_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 2 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/stealth-splitter/test_snapshots/test/test_create_split_different_salt_different_id.1.json b/stellar/stealth-splitter/test_snapshots/test/test_create_split_different_salt_different_id.1.json index a9ee2b7..7691bf5 100644 --- a/stellar/stealth-splitter/test_snapshots/test/test_create_split_different_salt_different_id.1.json +++ b/stellar/stealth-splitter/test_snapshots/test/test_create_split_different_salt_different_id.1.json @@ -458,6 +458,100 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "crt_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "benef_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/stealth-splitter/test_snapshots/test/test_create_split_emits_metric_events.1.json b/stellar/stealth-splitter/test_snapshots/test/test_create_split_emits_metric_events.1.json new file mode 100644 index 0000000..7157af2 --- /dev/null +++ b/stellar/stealth-splitter/test_snapshots/test/test_create_split_emits_metric_events.1.json @@ -0,0 +1,474 @@ +{ + "generators": { + "address": 4, + "nonce": 0 + }, + "auth": [ + [], + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_split", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "meta_address" + }, + "val": { + "bytes": "0a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243444546474849" + } + }, + { + "key": { + "symbol": "weight" + }, + "val": { + "u128": { + "hi": 0, + "lo": 101 + } + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "meta_address" + }, + "val": { + "bytes": "1415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253" + } + }, + { + "key": { + "symbol": "weight" + }, + "val": { + "u128": { + "hi": 0, + "lo": 102 + } + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "meta_address" + }, + "val": { + "bytes": "1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d" + } + }, + { + "key": { + "symbol": "weight" + }, + "val": { + "u128": { + "hi": 0, + "lo": 103 + } + } + } + ] + } + ] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "bytes": "6d65747269632d73616c74" + } + ] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Announcer" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Split" + }, + { + "bytes": "a45ad0a0df755747e7e2e2d21d76bb9e24636223e7acdb19a386c220b87917f6" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "asset" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "beneficiaries" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "meta_address" + }, + "val": { + "bytes": "0a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243444546474849" + } + }, + { + "key": { + "symbol": "weight" + }, + "val": { + "u128": { + "hi": 0, + "lo": 101 + } + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "meta_address" + }, + "val": { + "bytes": "1415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253" + } + }, + { + "key": { + "symbol": "weight" + }, + "val": { + "u128": { + "hi": 0, + "lo": 102 + } + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "meta_address" + }, + "val": { + "bytes": "1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d" + } + }, + { + "key": { + "symbol": "weight" + }, + "val": { + "u128": { + "hi": 0, + "lo": 103 + } + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "creator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "salt" + }, + "val": { + "bytes": "6d65747269632d73616c74" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "SplitFunded" + }, + { + "bytes": "a45ad0a0df755747e7e2e2d21d76bb9e24636223e7acdb19a386c220b87917f6" + } + ] + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "create" + }, + { + "bytes": "a45ad0a0df755747e7e2e2d21d76bb9e24636223e7acdb19a386c220b87917f6" + } + ], + "data": { + "u32": 3 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "crt_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "benef_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 3 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/stealth-splitter/test_snapshots/test/test_create_split_max_beneficiaries.1.json b/stellar/stealth-splitter/test_snapshots/test/test_create_split_max_beneficiaries.1.json index a30c1e9..b412ce7 100644 --- a/stellar/stealth-splitter/test_snapshots/test/test_create_split_max_beneficiaries.1.json +++ b/stellar/stealth-splitter/test_snapshots/test/test_create_split_max_beneficiaries.1.json @@ -1387,6 +1387,100 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "crt_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "benef_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 25 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/stealth-splitter/test_snapshots/test/test_create_split_single_beneficiary.1.json b/stellar/stealth-splitter/test_snapshots/test/test_create_split_single_beneficiary.1.json index a4e1c8f..d752ffb 100644 --- a/stellar/stealth-splitter/test_snapshots/test/test_create_split_single_beneficiary.1.json +++ b/stellar/stealth-splitter/test_snapshots/test/test_create_split_single_beneficiary.1.json @@ -283,6 +283,100 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "crt_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "benef_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/stealth-splitter/test_snapshots/test/test_fund_split_emits_metric_events.1.json b/stellar/stealth-splitter/test_snapshots/test/test_fund_split_emits_metric_events.1.json new file mode 100644 index 0000000..0fd8a96 --- /dev/null +++ b/stellar/stealth-splitter/test_snapshots/test/test_fund_split_emits_metric_events.1.json @@ -0,0 +1,1138 @@ +{ + "generators": { + "address": 7, + "nonce": 0 + }, + "auth": [ + [], + [], + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF", + { + "function": { + "contract_fn": { + "contract_address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "create_split", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "meta_address" + }, + "val": { + "bytes": "0a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243444546474849" + } + }, + { + "key": { + "symbol": "weight" + }, + "val": { + "u128": { + "hi": 0, + "lo": 101 + } + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "meta_address" + }, + "val": { + "bytes": "1415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253" + } + }, + { + "key": { + "symbol": "weight" + }, + "val": { + "u128": { + "hi": 0, + "lo": 102 + } + } + } + ] + } + ] + }, + { + "address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN" + }, + { + "bytes": "66756e642d6d65747269632d73616c74" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "fund_split", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "bytes": "8189aa433d356a476ed5a56b6913e7eadc164870061284951adf9dbf10cbb847" + }, + { + "i128": { + "hi": 0, + "lo": 6000 + } + }, + { + "u32": 1 + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + ] + }, + { + "vec": [ + { + "bytes": "0101010101010101010101010101010101010101010101010101010101010101" + }, + { + "bytes": "0202020202020202020202020202020202020202020202020202020202020202" + } + ] + }, + { + "vec": [ + { + "bytes": "01" + }, + { + "bytes": "02" + } + ] + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 6000 + } + } + ] + } + }, + "sub_invocations": [] + }, + { + "function": { + "contract_fn": { + "contract_address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + }, + { + "i128": { + "hi": 0, + "lo": 3014 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Announcer" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Split" + }, + { + "bytes": "8189aa433d356a476ed5a56b6913e7eadc164870061284951adf9dbf10cbb847" + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "asset" + }, + "val": { + "address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN" + } + }, + { + "key": { + "symbol": "beneficiaries" + }, + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "meta_address" + }, + "val": { + "bytes": "0a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243444546474849" + } + }, + { + "key": { + "symbol": "weight" + }, + "val": { + "u128": { + "hi": 0, + "lo": 101 + } + } + } + ] + }, + { + "map": [ + { + "key": { + "symbol": "meta_address" + }, + "val": { + "bytes": "1415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253" + } + }, + { + "key": { + "symbol": "weight" + }, + "val": { + "u128": { + "hi": 0, + "lo": 102 + } + } + } + ] + } + ] + } + }, + { + "key": { + "symbol": "creator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + }, + { + "key": { + "symbol": "salt" + }, + "val": { + "bytes": "66756e642d6d65747269632d73616c74" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "SplitFunded" + }, + { + "bytes": "8189aa433d356a476ed5a56b6913e7eadc164870061284951adf9dbf10cbb847" + } + ] + }, + "val": { + "i128": { + "hi": 0, + "lo": 6000 + } + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 986 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 6000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 3014 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000004" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 120960 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "8011bbf4cdf04e5bc6ac886935b99aa4b2c0cabde133f9d7fb3e656799f0a896", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "transfer" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF" + } + ], + "data": { + "i128": { + "hi": 0, + "lo": 6000 + } + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "8011bbf4cdf04e5bc6ac886935b99aa4b2c0cabde133f9d7fb3e656799f0a896", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "transfer" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM" + }, + { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF" + } + ], + "data": { + "i128": { + "hi": 0, + "lo": 3014 + } + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000002", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "fund" + }, + { + "bytes": "8189aa433d356a476ed5a56b6913e7eadc164870061284951adf9dbf10cbb847" + } + ], + "data": { + "i128": { + "hi": 0, + "lo": 6000 + } + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000002", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "fund_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000002", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_split" + }, + { + "symbol": "fund_vol" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 6000 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/stealth-vault/Cargo.toml b/stellar/stealth-vault/Cargo.toml index 76770a8..83a24b7 100644 --- a/stellar/stealth-vault/Cargo.toml +++ b/stellar/stealth-vault/Cargo.toml @@ -8,6 +8,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] soroban-sdk = { workspace = true } +wraith-metrics = { path = "../wraith-metrics" } [dev-dependencies] soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/stellar/stealth-vault/src/lib.rs b/stellar/stealth-vault/src/lib.rs index 22654f7..3ccfc88 100644 --- a/stellar/stealth-vault/src/lib.rs +++ b/stellar/stealth-vault/src/lib.rs @@ -2,7 +2,9 @@ use soroban_sdk::{ contract, contracterror, contractimpl, contracttype, token, Address, Bytes, BytesN, Env, + IntoVal, }; +use wraith_metrics::{contract_ids, dimension_names, emit_metric, metric_names}; const GRACE_PERIOD: u32 = 1000; const TTL_THRESHOLD: u32 = 17280; @@ -159,7 +161,25 @@ impl StealthVaultContract { // Emit deposit event env.events().publish( (soroban_sdk::symbol_short!("deposit"), deposit_id.clone()), - (sender, amount, asset, unlock_ledger), + (sender, amount, asset.clone(), unlock_ledger), + ); + + // Emit metric events. + let dimensions = + soroban_sdk::vec![&env, (dimension_names::ASSET_ADDRESS, asset.into_val(&env))]; + emit_metric( + &env, + contract_ids::STEALTH_VAULT, + metric_names::DEPOSIT_COUNT, + 1, + dimensions.clone(), + ); + emit_metric( + &env, + contract_ids::STEALTH_VAULT, + metric_names::DEPOSIT_VOLUME, + amount, + dimensions, ); Ok(deposit_id) @@ -197,6 +217,18 @@ impl StealthVaultContract { (recipient, entry.amount), ); + // Emit metric event. + emit_metric( + &env, + contract_ids::STEALTH_VAULT, + metric_names::CLAIM_COUNT, + 1, + soroban_sdk::vec![ + &env, + (dimension_names::ASSET_ADDRESS, entry.asset.into_val(&env)) + ], + ); + Ok(()) } @@ -228,6 +260,18 @@ impl StealthVaultContract { (entry.sender, entry.amount), ); + // Emit metric event. + emit_metric( + &env, + contract_ids::STEALTH_VAULT, + metric_names::REFUND_COUNT, + 1, + soroban_sdk::vec![ + &env, + (dimension_names::ASSET_ADDRESS, entry.asset.into_val(&env)) + ], + ); + Ok(()) } } @@ -235,7 +279,7 @@ impl StealthVaultContract { #[cfg(test)] mod test { use super::*; - use soroban_sdk::testutils::{Address as _, Ledger}; + use soroban_sdk::testutils::{Address as _, Events, Ledger}; use soroban_sdk::{Bytes, BytesN, Env}; #[contract] @@ -377,4 +421,90 @@ mod test { let res = client.try_refund(&deposit_id); assert_eq!(res, Err(Ok(VaultError::NotYetRefundable))); } + + // ============ METRIC EVENT SHAPE ============ + + /// Collect the `("metric", contract, name)` events currently in the buffer + /// as `(metric_name, value, asset_address_dimension)` triples. + fn metric_events(env: &Env) -> soroban_sdk::Vec<(soroban_sdk::Symbol, i128, Address)> { + let metric_topic: soroban_sdk::Val = soroban_sdk::symbol_short!("metric").into_val(env); + let mut collected = soroban_sdk::Vec::new(env); + + for (_, topics, data) in env.events().all().iter() { + let first: Option = topics.first(); + if first.map(|t| t.shallow_eq(&metric_topic)) != Some(true) { + continue; + } + + assert_eq!( + topics.len(), + 3, + "metric topics are (metric, contract, name)" + ); + let emitting: soroban_sdk::Symbol = topics.get(1).unwrap().into_val(env); + assert_eq!(emitting, contract_ids::STEALTH_VAULT); + + let metric_name: soroban_sdk::Symbol = topics.get(2).unwrap().into_val(env); + let (value, dimensions): ( + i128, + soroban_sdk::Vec<(soroban_sdk::Symbol, soroban_sdk::Val)>, + ) = data.into_val(env); + + assert_eq!(dimensions.len(), 1, "expected the asset_address dimension"); + let (dimension_name, dimension_value) = dimensions.get(0).unwrap(); + assert_eq!(dimension_name, dimension_names::ASSET_ADDRESS); + let asset: Address = dimension_value.into_val(env); + + collected.push_back((metric_name, value, asset)); + } + + collected + } + + #[test] + fn test_deposit_emits_metric_events() { + let (env, client, sender, recipient, token_id) = setup(); + let epk = BytesN::from_array(&env, &[9u8; 32]); + + client.deposit(&sender, &recipient, &1000, &token_id, &100, &2000, &epk); + + assert_eq!( + metric_events(&env), + soroban_sdk::vec![ + &env, + (metric_names::DEPOSIT_COUNT, 1i128, token_id.clone()), + (metric_names::DEPOSIT_VOLUME, 1000i128, token_id), + ] + ); + } + + #[test] + fn test_claim_emits_metric_event() { + let (env, client, sender, recipient, token_id) = setup(); + let epk = BytesN::from_array(&env, &[10u8; 32]); + + let deposit_id = client.deposit(&sender, &recipient, &1000, &token_id, &100, &2000, &epk); + env.ledger().with_mut(|li| li.sequence_number = 100); + client.claim(&deposit_id, &recipient); + + assert_eq!( + metric_events(&env), + soroban_sdk::vec![&env, (metric_names::CLAIM_COUNT, 1i128, token_id)] + ); + } + + #[test] + fn test_refund_emits_metric_event() { + let (env, client, sender, recipient, token_id) = setup(); + let epk = BytesN::from_array(&env, &[11u8; 32]); + + let deposit_id = client.deposit(&sender, &recipient, &800, &token_id, &100, &2000, &epk); + env.ledger().with_mut(|li| li.sequence_number = 2000); + client.refund(&deposit_id); + + assert_eq!( + metric_events(&env), + soroban_sdk::vec![&env, (metric_names::REFUND_COUNT, 1i128, token_id)] + ); + } } diff --git a/stellar/stealth-vault/test_snapshots/test/test_claim_emits_metric_event.1.json b/stellar/stealth-vault/test_snapshots/test/test_claim_emits_metric_event.1.json new file mode 100644 index 0000000..feecce0 --- /dev/null +++ b/stellar/stealth-vault/test_snapshots/test/test_claim_emits_metric_event.1.json @@ -0,0 +1,856 @@ +{ + "generators": { + "address": 6, + "nonce": 0 + }, + "auth": [ + [], + [], + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF", + { + "function": { + "contract_fn": { + "contract_address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + { + "function": { + "contract_fn": { + "contract_address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "deposit", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN" + }, + { + "u32": 100 + }, + { + "u32": 2000 + }, + { + "bytes": "0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "claim", + "args": [ + { + "bytes": "17aa3ba0c2fb06c042a8a926c95fc706fa40bfdac6160e65107bc12f4cffdbbd" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 100, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 600000, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Announcer" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6312099 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 9000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 600099 + ] + ], + [ + { + "contract_data": { + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000006" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 599999 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "04cadb4a570fd2e4652e814101509912cce6c9a2325d6eec8d7100caf859f3e0", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "transfer" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF" + } + ], + "data": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000002", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "claim" + }, + { + "bytes": "17aa3ba0c2fb06c042a8a926c95fc706fa40bfdac6160e65107bc12f4cffdbbd" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000002", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_vault" + }, + { + "symbol": "clm_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/stealth-vault/test_snapshots/test/test_deposit_emits_metric_events.1.json b/stellar/stealth-vault/test_snapshots/test/test_deposit_emits_metric_events.1.json new file mode 100644 index 0000000..8b906c6 --- /dev/null +++ b/stellar/stealth-vault/test_snapshots/test/test_deposit_emits_metric_events.1.json @@ -0,0 +1,878 @@ +{ + "generators": { + "address": 6, + "nonce": 0 + }, + "auth": [ + [], + [], + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF", + { + "function": { + "contract_fn": { + "contract_address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + { + "function": { + "contract_fn": { + "contract_address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "deposit", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN" + }, + { + "u32": 100 + }, + { + "u32": 2000 + }, + { + "bytes": "0909090909090909090909090909090909090909090909090909090909090909" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 600000, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "Deposit" + }, + { + "bytes": "061d2669b8d4cc481004c745beb14872f68ce4b5488a36929a1e578da8254b05" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "vec": [ + { + "symbol": "Deposit" + }, + { + "bytes": "061d2669b8d4cc481004c745beb14872f68ce4b5488a36929a1e578da8254b05" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "asset" + }, + "val": { + "address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN" + } + }, + { + "key": { + "symbol": "recipient" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + }, + { + "key": { + "symbol": "refund_after" + }, + "val": { + "u32": 2000 + } + }, + { + "key": { + "symbol": "sender" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "unlock_ledger" + }, + "val": { + "u32": 100 + } + } + ] + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Announcer" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 9000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000006" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 599999 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "04cadb4a570fd2e4652e814101509912cce6c9a2325d6eec8d7100caf859f3e0", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "transfer" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF" + } + ], + "data": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000002", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "deposit" + }, + { + "bytes": "061d2669b8d4cc481004c745beb14872f68ce4b5488a36929a1e578da8254b05" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN" + }, + { + "u32": 100 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000002", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_vault" + }, + { + "symbol": "dep_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000002", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_vault" + }, + { + "symbol": "dep_vol" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1000 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/stealth-vault/test_snapshots/test/test_refund_emits_metric_event.1.json b/stellar/stealth-vault/test_snapshots/test/test_refund_emits_metric_event.1.json new file mode 100644 index 0000000..2a76267 --- /dev/null +++ b/stellar/stealth-vault/test_snapshots/test/test_refund_emits_metric_event.1.json @@ -0,0 +1,780 @@ +{ + "generators": { + "address": 6, + "nonce": 0 + }, + "auth": [ + [], + [], + [], + [ + [ + "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF", + { + "function": { + "contract_fn": { + "contract_address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "function_name": "set_admin", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + { + "function": { + "contract_fn": { + "contract_address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "function_name": "mint", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 10000 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "deposit", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 800 + } + }, + { + "address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN" + }, + { + "u32": 100 + }, + { + "u32": 2000 + }, + { + "bytes": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" + } + ] + } + }, + "sub_invocations": [ + { + "function": { + "contract_fn": { + "contract_address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "function_name": "transfer", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 800 + } + } + ] + } + }, + "sub_invocations": [] + } + ] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "function_name": "refund", + "args": [ + { + "bytes": "5f0b4f4c3397785e8829a567fb28cd7caa77ac8372728b1cf93e3c4997c057dd" + } + ] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 2000, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 600000, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "account": { + "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF", + "balance": 0, + "seq_num": 0, + "num_sub_entries": 0, + "inflation_dest": null, + "flags": 0, + "home_domain": "", + "thresholds": "01010101", + "signers": [], + "ext": "v0" + } + }, + "ext": "v0" + }, + null + ] + ], + [ + { + "contract_data": { + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": [ + { + "key": { + "vec": [ + { + "symbol": "Announcer" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6313999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 0 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": { + "vec": [ + { + "symbol": "Balance" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 10000 + } + } + }, + { + "key": { + "symbol": "authorized" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "clawback" + }, + "val": { + "bool": false + } + } + ] + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_data": { + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": "stellar_asset", + "storage": [ + { + "key": { + "symbol": "METADATA" + }, + "val": { + "map": [ + { + "key": { + "symbol": "decimal" + }, + "val": { + "u32": 7 + } + }, + { + "key": { + "symbol": "name" + }, + "val": { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF" + } + }, + { + "key": { + "symbol": "symbol" + }, + "val": { + "string": "aaa" + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "AssetInfo" + } + ] + }, + "val": { + "vec": [ + { + "symbol": "AlphaNum4" + }, + { + "map": [ + { + "key": { + "symbol": "asset_code" + }, + "val": { + "string": "aaa\\0" + } + }, + { + "key": { + "symbol": "issuer" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000006" + } + } + ] + } + ] + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 599999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 599999 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "04cadb4a570fd2e4652e814101509912cce6c9a2325d6eec8d7100caf859f3e0", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "transfer" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANHUF" + } + ], + "data": { + "i128": { + "hi": 0, + "lo": 800 + } + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000002", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "refund" + }, + { + "bytes": "5f0b4f4c3397785e8829a567fb28cd7caa77ac8372728b1cf93e3c4997c057dd" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "i128": { + "hi": 0, + "lo": 800 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000002", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "st_vault" + }, + { + "symbol": "rfnd_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [ + { + "vec": [ + { + "symbol": "ast_addr" + }, + { + "address": "CACMVW2KK4H5FZDFF2AUCAKQTEJMZZWJUIZF23XMRVYQBSXYLHZ6BKWN" + } + ] + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/wraith-metrics/src/lib.rs b/stellar/wraith-metrics/src/lib.rs index 7c1a910..1adb7d8 100644 --- a/stellar/wraith-metrics/src/lib.rs +++ b/stellar/wraith-metrics/src/lib.rs @@ -53,6 +53,29 @@ pub mod metric_names { pub const BATCH_SEND_VOLUME: soroban_sdk::Symbol = symbol_short!("bat_vol"); pub const BATCH_SIZE: soroban_sdk::Symbol = symbol_short!("bat_size"); pub const ERROR_COUNT: soroban_sdk::Symbol = symbol_short!("err_cnt"); + + // wraith-names + pub const RENEW_COUNT: soroban_sdk::Symbol = symbol_short!("renew_cnt"); + pub const RELEASE_COUNT: soroban_sdk::Symbol = symbol_short!("rel_cnt"); + pub const RESOLVE_HIT_COUNT: soroban_sdk::Symbol = symbol_short!("res_hit"); + pub const RESOLVE_MISS_COUNT: soroban_sdk::Symbol = symbol_short!("res_miss"); + + // stealth-splitter + pub const CREATE_COUNT: soroban_sdk::Symbol = symbol_short!("crt_cnt"); + pub const FUND_COUNT: soroban_sdk::Symbol = symbol_short!("fund_cnt"); + pub const FUND_VOLUME: soroban_sdk::Symbol = symbol_short!("fund_vol"); + pub const BENEFICIARIES_PER_SPLIT: soroban_sdk::Symbol = symbol_short!("benef_cnt"); + + // stealth-vault + pub const DEPOSIT_COUNT: soroban_sdk::Symbol = symbol_short!("dep_cnt"); + pub const DEPOSIT_VOLUME: soroban_sdk::Symbol = symbol_short!("dep_vol"); + pub const CLAIM_COUNT: soroban_sdk::Symbol = symbol_short!("clm_cnt"); + pub const REFUND_COUNT: soroban_sdk::Symbol = symbol_short!("rfnd_cnt"); + + // governance + pub const PROPOSAL_COUNT: soroban_sdk::Symbol = symbol_short!("prop_cnt"); + pub const VOTE_COUNT: soroban_sdk::Symbol = symbol_short!("vote_cnt"); + pub const EXECUTION_COUNT: soroban_sdk::Symbol = symbol_short!("exec_cnt"); } /// Standard contract identifiers @@ -63,6 +86,10 @@ pub mod contract_ids { pub const STEALTH_SENDER: soroban_sdk::Symbol = symbol_short!("st_send"); pub const STEALTH_BATCH_SENDER: soroban_sdk::Symbol = symbol_short!("st_bat_sd"); pub const STEALTH_ANNOUNCER: soroban_sdk::Symbol = symbol_short!("st_ann"); + pub const WRAITH_NAMES: soroban_sdk::Symbol = symbol_short!("wr_names"); + pub const STEALTH_SPLITTER: soroban_sdk::Symbol = symbol_short!("st_split"); + pub const STEALTH_VAULT: soroban_sdk::Symbol = symbol_short!("st_vault"); + pub const GOVERNANCE: soroban_sdk::Symbol = symbol_short!("gov"); } /// Standard dimension names @@ -73,4 +100,6 @@ pub mod dimension_names { pub const TOKEN_ADDRESS: soroban_sdk::Symbol = symbol_short!("tok_addr"); pub const ASSET_ADDRESS: soroban_sdk::Symbol = symbol_short!("ast_addr"); pub const ERROR_CODE: soroban_sdk::Symbol = symbol_short!("err_code"); + pub const PROPOSAL_ID: soroban_sdk::Symbol = symbol_short!("prop_id"); + pub const SUPPORT: soroban_sdk::Symbol = symbol_short!("support"); } diff --git a/stellar/wraith-names/Cargo.toml b/stellar/wraith-names/Cargo.toml index cc85bbb..3cd9f1b 100644 --- a/stellar/wraith-names/Cargo.toml +++ b/stellar/wraith-names/Cargo.toml @@ -11,6 +11,7 @@ testutils = ["soroban-sdk/testutils"] [dependencies] soroban-sdk = { workspace = true } +wraith-metrics = { path = "../wraith-metrics" } [dev-dependencies] proptest = "1.6.0" diff --git a/stellar/wraith-names/src/lib.rs b/stellar/wraith-names/src/lib.rs index 5624fcf..9073915 100644 --- a/stellar/wraith-names/src/lib.rs +++ b/stellar/wraith-names/src/lib.rs @@ -9,6 +9,7 @@ use soroban_sdk::{ contract, contracterror, contractimpl, contracttype, symbol_short, Address, Bytes, BytesN, Env, String, Vec, }; +use wraith_metrics::{contract_ids, emit_metric, metric_names}; pub mod auction; mod multisig; @@ -434,6 +435,15 @@ impl WraithNamesContract { (name_hashes, extend_to_ledger), ); + // Emit metric event — one renewal per name in the batch. + emit_metric( + &env, + contract_ids::WRAITH_NAMES, + metric_names::RENEW_COUNT, + count as i128, + Vec::new(&env), + ); + Ok(()) } @@ -547,6 +557,15 @@ impl WraithNamesContract { (name, stealth_meta_address), ); + // Emit metric event. + emit_metric( + env, + contract_ids::WRAITH_NAMES, + metric_names::REGISTER_COUNT, + 1, + Vec::new(env), + ); + Ok(()) } @@ -629,6 +648,15 @@ impl WraithNamesContract { env.events() .publish((symbol_short!("release"), name_hash), name); + // Emit metric event. + emit_metric( + env, + contract_ids::WRAITH_NAMES, + metric_names::RELEASE_COUNT, + 1, + Vec::new(env), + ); + Ok(()) } @@ -693,14 +721,33 @@ impl WraithNamesContract { pub fn resolve(env: Env, name: String) -> Result { let name_hash = Self::hash_name(&env, &name); let name_key = DataKey::Name(name_hash); - let entry: NameEntry = env - .storage() - .persistent() - .get(&name_key) - .ok_or(NamesError::NameNotFound)?; + let entry: NameEntry = match env.storage().persistent().get(&name_key) { + Some(entry) => entry, + None => { + // Emit metric event. Published before the error is returned, so + // it is captured whenever the enclosing transaction is applied. + emit_metric( + &env, + contract_ids::WRAITH_NAMES, + metric_names::RESOLVE_MISS_COUNT, + 1, + Vec::new(&env), + ); + return Err(NamesError::NameNotFound); + } + }; Self::extend_ttls(&env, &name_key, None); + // Emit metric event. + emit_metric( + &env, + contract_ids::WRAITH_NAMES, + metric_names::RESOLVE_HIT_COUNT, + 1, + Vec::new(&env), + ); + Ok(entry.stealth_meta_address) } @@ -774,6 +821,15 @@ impl WraithNamesContract { env.events() .publish((symbol_short!("extend"), name_hash), extend_to_ledger); + // Emit metric event. + emit_metric( + &env, + contract_ids::WRAITH_NAMES, + metric_names::RENEW_COUNT, + 1, + Vec::new(&env), + ); + Ok(()) } diff --git a/stellar/wraith-names/test_snapshots/adversarial_name_32_chars_accepted.1.json b/stellar/wraith-names/test_snapshots/adversarial_name_32_chars_accepted.1.json index 828ae32..323ed1c 100644 --- a/stellar/wraith-names/test_snapshots/adversarial_name_32_chars_accepted.1.json +++ b/stellar/wraith-names/test_snapshots/adversarial_name_32_chars_accepted.1.json @@ -251,5 +251,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/adversarial_name_mixed_alphanumeric_accepted.1.json b/stellar/wraith-names/test_snapshots/adversarial_name_mixed_alphanumeric_accepted.1.json index 2e39419..146b619 100644 --- a/stellar/wraith-names/test_snapshots/adversarial_name_mixed_alphanumeric_accepted.1.json +++ b/stellar/wraith-names/test_snapshots/adversarial_name_mixed_alphanumeric_accepted.1.json @@ -251,5 +251,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/adversarial_name_numbers_only_accepted.1.json b/stellar/wraith-names/test_snapshots/adversarial_name_numbers_only_accepted.1.json index 63580bc..dec8748 100644 --- a/stellar/wraith-names/test_snapshots/adversarial_name_numbers_only_accepted.1.json +++ b/stellar/wraith-names/test_snapshots/adversarial_name_numbers_only_accepted.1.json @@ -251,5 +251,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/adversarial_name_starts_with_digit_accepted.1.json b/stellar/wraith-names/test_snapshots/adversarial_name_starts_with_digit_accepted.1.json index ec1a203..70f536c 100644 --- a/stellar/wraith-names/test_snapshots/adversarial_name_starts_with_digit_accepted.1.json +++ b/stellar/wraith-names/test_snapshots/adversarial_name_starts_with_digit_accepted.1.json @@ -251,5 +251,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/adversarial_on_behalf_different_operations_distinct_replay_keys.1.json b/stellar/wraith-names/test_snapshots/adversarial_on_behalf_different_operations_distinct_replay_keys.1.json index 44be4fa..6d22e25 100644 --- a/stellar/wraith-names/test_snapshots/adversarial_on_behalf_different_operations_distinct_replay_keys.1.json +++ b/stellar/wraith-names/test_snapshots/adversarial_on_behalf_different_operations_distinct_replay_keys.1.json @@ -212,5 +212,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_miss" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": true + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/adversarial_update_invalid_meta_address_rejected.1.json b/stellar/wraith-names/test_snapshots/adversarial_update_invalid_meta_address_rejected.1.json index 4e5b1ad..b9340b6 100644 --- a/stellar/wraith-names/test_snapshots/adversarial_update_invalid_meta_address_rejected.1.json +++ b/stellar/wraith-names/test_snapshots/adversarial_update_invalid_meta_address_rejected.1.json @@ -252,5 +252,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/bulk_renew_emits_renew_count_metric_carrying_batch_size.1.json b/stellar/wraith-names/test_snapshots/bulk_renew_emits_renew_count_metric_carrying_batch_size.1.json new file mode 100644 index 0000000..fa37281 --- /dev/null +++ b/stellar/wraith-names/test_snapshots/bulk_renew_emits_renew_count_metric_carrying_batch_size.1.json @@ -0,0 +1,551 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "register", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "alpha" + }, + { + "bytes": "01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "register", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "beta" + }, + { + "bytes": "02020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Name" + }, + { + "bytes": "8ed3f6ad685b959ead7022518e1af76cd816f8e8ec7ccdda1ed4018e8f2223f8" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Name" + }, + { + "bytes": "8ed3f6ad685b959ead7022518e1af76cd816f8e8ec7ccdda1ed4018e8f2223f8" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "name" + }, + "val": { + "string": "alpha" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "parent" + }, + "val": "void" + }, + { + "key": { + "symbol": "stealth_meta_address" + }, + "val": { + "bytes": "01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Name" + }, + { + "bytes": "f44e64e75f3948e9f73f8dfa94721c4ce8cbb4f265c4790c702b2d41cfbf2753" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Name" + }, + { + "bytes": "f44e64e75f3948e9f73f8dfa94721c4ce8cbb4f265c4790c702b2d41cfbf2753" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "name" + }, + "val": { + "string": "beta" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "parent" + }, + "val": "void" + }, + { + "key": { + "symbol": "stealth_meta_address" + }, + "val": { + "bytes": "02020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Reverse" + }, + { + "bytes": "7c8975e1e60a5c8337f28edf8c33c3b180360b7279644a9bc1af3c51e6220bf5" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Reverse" + }, + { + "bytes": "7c8975e1e60a5c8337f28edf8c33c3b180360b7279644a9bc1af3c51e6220bf5" + } + ] + }, + "durability": "persistent", + "val": { + "bytes": "8ed3f6ad685b959ead7022518e1af76cd816f8e8ec7ccdda1ed4018e8f2223f8" + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Reverse" + }, + { + "bytes": "f83b332be4e6a5a4b1c56aaf6db52657da495e149870057d8590ab9d7a6167ad" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Reverse" + }, + { + "bytes": "f83b332be4e6a5a4b1c56aaf6db52657da495e149870057d8590ab9d7a6167ad" + } + ] + }, + "durability": "persistent", + "val": { + "bytes": "f44e64e75f3948e9f73f8dfa94721c4ce8cbb4f265c4790c702b2d41cfbf2753" + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "extend" + }, + { + "bytes": "8ed3f6ad685b959ead7022518e1af76cd816f8e8ec7ccdda1ed4018e8f2223f8" + } + ], + "data": { + "u32": 10000 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "extend" + }, + { + "bytes": "f44e64e75f3948e9f73f8dfa94721c4ce8cbb4f265c4790c702b2d41cfbf2753" + } + ], + "data": { + "u32": 10000 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "blk_renew" + } + ], + "data": { + "vec": [ + { + "vec": [ + { + "bytes": "8ed3f6ad685b959ead7022518e1af76cd816f8e8ec7ccdda1ed4018e8f2223f8" + }, + { + "bytes": "f44e64e75f3948e9f73f8dfa94721c4ce8cbb4f265c4790c702b2d41cfbf2753" + } + ] + }, + { + "u32": 10000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "renew_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 2 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/extend_name_ttl_emits_renew_count_metric.1.json b/stellar/wraith-names/test_snapshots/extend_name_ttl_emits_renew_count_metric.1.json new file mode 100644 index 0000000..9aa2db5 --- /dev/null +++ b/stellar/wraith-names/test_snapshots/extend_name_ttl_emits_renew_count_metric.1.json @@ -0,0 +1,315 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "register", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "alice" + }, + { + "bytes": "01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Name" + }, + { + "bytes": "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Name" + }, + { + "bytes": "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "name" + }, + "val": { + "string": "alice" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "parent" + }, + "val": "void" + }, + { + "key": { + "symbol": "stealth_meta_address" + }, + "val": { + "bytes": "01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Reverse" + }, + { + "bytes": "7c8975e1e60a5c8337f28edf8c33c3b180360b7279644a9bc1af3c51e6220bf5" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Reverse" + }, + { + "bytes": "7c8975e1e60a5c8337f28edf8c33c3b180360b7279644a9bc1af3c51e6220bf5" + } + ] + }, + "durability": "persistent", + "val": { + "bytes": "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90" + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "extend" + }, + { + "bytes": "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90" + } + ], + "data": { + "u32": 10000 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "renew_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/register_emits_register_count_metric.1.json b/stellar/wraith-names/test_snapshots/register_emits_register_count_metric.1.json new file mode 100644 index 0000000..f70544e --- /dev/null +++ b/stellar/wraith-names/test_snapshots/register_emits_register_count_metric.1.json @@ -0,0 +1,321 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "register", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "alice" + }, + { + "bytes": "01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + } + ] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Name" + }, + { + "bytes": "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Name" + }, + { + "bytes": "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "name" + }, + "val": { + "string": "alice" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "parent" + }, + "val": "void" + }, + { + "key": { + "symbol": "stealth_meta_address" + }, + "val": { + "bytes": "01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Reverse" + }, + { + "bytes": "7c8975e1e60a5c8337f28edf8c33c3b180360b7279644a9bc1af3c51e6220bf5" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Reverse" + }, + { + "bytes": "7c8975e1e60a5c8337f28edf8c33c3b180360b7279644a9bc1af3c51e6220bf5" + } + ] + }, + "durability": "persistent", + "val": { + "bytes": "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90" + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "register" + }, + { + "bytes": "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90" + } + ], + "data": { + "vec": [ + { + "string": "alice" + }, + { + "bytes": "01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "reg_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/release_emits_release_count_metric.1.json b/stellar/wraith-names/test_snapshots/release_emits_release_count_metric.1.json new file mode 100644 index 0000000..386ed53 --- /dev/null +++ b/stellar/wraith-names/test_snapshots/release_emits_release_count_metric.1.json @@ -0,0 +1,248 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "register", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "alice" + }, + { + "bytes": "01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "release", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "alice" + } + ] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "release" + }, + { + "bytes": "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90" + } + ], + "data": { + "string": "alice" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "rel_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/resolve_emits_hit_metric.1.json b/stellar/wraith-names/test_snapshots/resolve_emits_hit_metric.1.json new file mode 100644 index 0000000..a817974 --- /dev/null +++ b/stellar/wraith-names/test_snapshots/resolve_emits_hit_metric.1.json @@ -0,0 +1,292 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "register", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "string": "alice" + }, + { + "bytes": "01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Name" + }, + { + "bytes": "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Name" + }, + { + "bytes": "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "name" + }, + "val": { + "string": "alice" + } + }, + { + "key": { + "symbol": "owner" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + }, + { + "key": { + "symbol": "parent" + }, + "val": "void" + }, + { + "key": { + "symbol": "stealth_meta_address" + }, + "val": { + "bytes": "01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + } + } + ] + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Reverse" + }, + { + "bytes": "7c8975e1e60a5c8337f28edf8c33c3b180360b7279644a9bc1af3c51e6220bf5" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "vec": [ + { + "symbol": "Reverse" + }, + { + "bytes": "7c8975e1e60a5c8337f28edf8c33c3b180360b7279644a9bc1af3c51e6220bf5" + } + ] + }, + "durability": "persistent", + "val": { + "bytes": "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90" + } + } + }, + "ext": "v0" + }, + 518400 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 801925984706572462 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/resolve_emits_miss_metric_before_returning_not_found.1.json b/stellar/wraith-names/test_snapshots/resolve_emits_miss_metric_before_returning_not_found.1.json new file mode 100644 index 0000000..68ad790 --- /dev/null +++ b/stellar/wraith-names/test_snapshots/resolve_emits_miss_metric_before_returning_not_found.1.json @@ -0,0 +1,113 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_miss" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": true + } + ] +} \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test/test_bulk_register_atomic_revert_on_taken.1.json b/stellar/wraith-names/test_snapshots/test/test_bulk_register_atomic_revert_on_taken.1.json index 735332c..67bdfca 100644 --- a/stellar/wraith-names/test_snapshots/test/test_bulk_register_atomic_revert_on_taken.1.json +++ b/stellar/wraith-names/test_snapshots/test/test_bulk_register_atomic_revert_on_taken.1.json @@ -253,5 +253,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_miss" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": true + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test/test_bulk_register_happy_path.1.json b/stellar/wraith-names/test_snapshots/test/test_bulk_register_happy_path.1.json index 2196644..997082a 100644 --- a/stellar/wraith-names/test_snapshots/test/test_bulk_register_happy_path.1.json +++ b/stellar/wraith-names/test_snapshots/test/test_bulk_register_happy_path.1.json @@ -515,5 +515,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test/test_bulk_renew_happy_path.1.json b/stellar/wraith-names/test_snapshots/test/test_bulk_renew_happy_path.1.json index 3dbb70b..fa37281 100644 --- a/stellar/wraith-names/test_snapshots/test/test_bulk_renew_happy_path.1.json +++ b/stellar/wraith-names/test_snapshots/test/test_bulk_renew_happy_path.1.json @@ -510,6 +510,42 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "renew_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 2 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test/test_register_and_resolve.1.json b/stellar/wraith-names/test_snapshots/test/test_register_and_resolve.1.json index 004ac82..a817974 100644 --- a/stellar/wraith-names/test_snapshots/test/test_register_and_resolve.1.json +++ b/stellar/wraith-names/test_snapshots/test/test_register_and_resolve.1.json @@ -251,5 +251,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test/test_register_on_behalf.1.json b/stellar/wraith-names/test_snapshots/test/test_register_on_behalf.1.json index ad2eecc..3cf0e3c 100644 --- a/stellar/wraith-names/test_snapshots/test/test_register_on_behalf.1.json +++ b/stellar/wraith-names/test_snapshots/test/test_register_on_behalf.1.json @@ -239,5 +239,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test/test_update_on_behalf_and_release_on_behalf.1.json b/stellar/wraith-names/test_snapshots/test/test_update_on_behalf_and_release_on_behalf.1.json index 6257edb..b5799ad 100644 --- a/stellar/wraith-names/test_snapshots/test/test_update_on_behalf_and_release_on_behalf.1.json +++ b/stellar/wraith-names/test_snapshots/test/test_update_on_behalf_and_release_on_behalf.1.json @@ -211,5 +211,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_miss" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": true + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_bulk_register_all_succeed.1.json b/stellar/wraith-names/test_snapshots/test_bulk_register_all_succeed.1.json index 2196644..997082a 100644 --- a/stellar/wraith-names/test_snapshots/test_bulk_register_all_succeed.1.json +++ b/stellar/wraith-names/test_snapshots/test_bulk_register_all_succeed.1.json @@ -515,5 +515,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_bulk_register_atomic_revert_on_invalid_meta.1.json b/stellar/wraith-names/test_snapshots/test_bulk_register_atomic_revert_on_invalid_meta.1.json index 64688ee..36ad51c 100644 --- a/stellar/wraith-names/test_snapshots/test_bulk_register_atomic_revert_on_invalid_meta.1.json +++ b/stellar/wraith-names/test_snapshots/test_bulk_register_atomic_revert_on_invalid_meta.1.json @@ -73,5 +73,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_miss" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": true + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_bulk_register_atomic_revert_on_taken.1.json b/stellar/wraith-names/test_snapshots/test_bulk_register_atomic_revert_on_taken.1.json index 735332c..67bdfca 100644 --- a/stellar/wraith-names/test_snapshots/test_bulk_register_atomic_revert_on_taken.1.json +++ b/stellar/wraith-names/test_snapshots/test_bulk_register_atomic_revert_on_taken.1.json @@ -253,5 +253,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_miss" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": true + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_bulk_register_emits_per_name_events.1.json b/stellar/wraith-names/test_snapshots/test_bulk_register_emits_per_name_events.1.json index 9a03d07..fe3ed3d 100644 --- a/stellar/wraith-names/test_snapshots/test_bulk_register_emits_per_name_events.1.json +++ b/stellar/wraith-names/test_snapshots/test_bulk_register_emits_per_name_events.1.json @@ -416,6 +416,42 @@ }, "failed_call": false }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "reg_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + }, { "event": { "ext": "v0", @@ -446,6 +482,42 @@ }, "failed_call": false }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "reg_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + }, { "event": { "ext": "v0", diff --git a/stellar/wraith-names/test_snapshots/test_bulk_register_invalid_name_reverts.1.json b/stellar/wraith-names/test_snapshots/test_bulk_register_invalid_name_reverts.1.json index 64688ee..36ad51c 100644 --- a/stellar/wraith-names/test_snapshots/test_bulk_register_invalid_name_reverts.1.json +++ b/stellar/wraith-names/test_snapshots/test_bulk_register_invalid_name_reverts.1.json @@ -73,5 +73,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_miss" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": true + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_bulk_renew_all_succeed.1.json b/stellar/wraith-names/test_snapshots/test_bulk_renew_all_succeed.1.json index 4f9b90c..142560e 100644 --- a/stellar/wraith-names/test_snapshots/test_bulk_renew_all_succeed.1.json +++ b/stellar/wraith-names/test_snapshots/test_bulk_renew_all_succeed.1.json @@ -431,5 +431,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_bulk_renew_emits_per_name_events.1.json b/stellar/wraith-names/test_snapshots/test_bulk_renew_emits_per_name_events.1.json index 3dbb70b..fa37281 100644 --- a/stellar/wraith-names/test_snapshots/test_bulk_renew_emits_per_name_events.1.json +++ b/stellar/wraith-names/test_snapshots/test_bulk_renew_emits_per_name_events.1.json @@ -510,6 +510,42 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "renew_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 2 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_contract_functional_during_upgrade_timelock.1.json b/stellar/wraith-names/test_snapshots/test_contract_functional_during_upgrade_timelock.1.json index f5c3b7c..4a35519 100644 --- a/stellar/wraith-names/test_snapshots/test_contract_functional_during_upgrade_timelock.1.json +++ b/stellar/wraith-names/test_snapshots/test_contract_functional_during_upgrade_timelock.1.json @@ -293,5 +293,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_miss" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": true + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_after_release_and_reregister.1.json b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_after_release_and_reregister.1.json index f83b3ef..2e7eb54 100644 --- a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_after_release_and_reregister.1.json +++ b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_after_release_and_reregister.1.json @@ -387,6 +387,42 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "renew_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_after_update.1.json b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_after_update.1.json index 950ea96..df5193f 100644 --- a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_after_update.1.json +++ b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_after_update.1.json @@ -310,5 +310,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_emits_event.1.json b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_emits_event.1.json index 8180a48..f9cbef9 100644 --- a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_emits_event.1.json +++ b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_emits_event.1.json @@ -274,6 +274,42 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "renew_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_happy_path.1.json b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_happy_path.1.json index 4440e2b..9aa2db5 100644 --- a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_happy_path.1.json +++ b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_happy_path.1.json @@ -274,6 +274,42 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "renew_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_idempotent.1.json b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_idempotent.1.json index c1b20f1..f92eb67 100644 --- a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_idempotent.1.json +++ b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_idempotent.1.json @@ -275,6 +275,42 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "renew_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_multiple_names.1.json b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_multiple_names.1.json index 7f6e597..beb37f0 100644 --- a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_multiple_names.1.json +++ b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_multiple_names.1.json @@ -409,6 +409,42 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "renew_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_permissionless.1.json b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_permissionless.1.json index 0566020..27d39ed 100644 --- a/stellar/wraith-names/test_snapshots/test_extend_name_ttl_permissionless.1.json +++ b/stellar/wraith-names/test_snapshots/test_extend_name_ttl_permissionless.1.json @@ -274,6 +274,42 @@ } }, "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "renew_cnt" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false } ] } \ No newline at end of file diff --git a/stellar/wraith-names/test_snapshots/test_renounced_contract_behaves_like_frozen.1.json b/stellar/wraith-names/test_snapshots/test_renounced_contract_behaves_like_frozen.1.json index 04a70b6..6079bab 100644 --- a/stellar/wraith-names/test_snapshots/test_renounced_contract_behaves_like_frozen.1.json +++ b/stellar/wraith-names/test_snapshots/test_renounced_contract_behaves_like_frozen.1.json @@ -299,5 +299,42 @@ ] ] }, - "events": [] + "events": [ + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "metric" + }, + { + "symbol": "wr_names" + }, + { + "symbol": "res_hit" + } + ], + "data": { + "vec": [ + { + "i128": { + "hi": 0, + "lo": 1 + } + }, + { + "vec": [] + } + ] + } + } + } + }, + "failed_call": false + } + ] } \ No newline at end of file diff --git a/stellar/wraith-names/tests/metrics.rs b/stellar/wraith-names/tests/metrics.rs new file mode 100644 index 0000000..b854b18 --- /dev/null +++ b/stellar/wraith-names/tests/metrics.rs @@ -0,0 +1,137 @@ +//! Asserts the shape of the WraithMetricEvent stream emitted by wraith-names. +//! +//! The wire contract that off-chain indexers depend on is +//! `(("metric", contract, metric_name), (value, dimensions))` — see +//! `stellar/METRICS.md`. These tests pin both halves. + +use soroban_sdk::testutils::{Address as _, Events}; +use soroban_sdk::{symbol_short, vec, Address, Bytes, Env, IntoVal, String, Val, Vec}; +use wraith_metrics::{contract_ids, metric_names}; +use wraith_names::{WraithNamesContract, WraithNamesContractClient}; + +fn setup() -> (Env, WraithNamesContractClient<'static>, Address) { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(WraithNamesContract, ()); + let client = WraithNamesContractClient::new(&env, &contract_id); + let owner = Address::generate(&env); + (env, client, owner) +} + +/// Return the (topics, data) of the single metric event in the buffer, +/// panicking when the count is anything other than one. +fn only_metric_event(env: &Env) -> (Vec, Val) { + let metric = symbol_short!("metric").into_val(env); + let mut found: Option<(Vec, Val)> = None; + + for (_, topics, data) in env.events().all().iter() { + if topics.first().map(|t: Val| t.shallow_eq(&metric)) == Some(true) { + assert!(found.is_none(), "expected exactly one metric event"); + found = Some((topics, data)); + } + } + + found.expect("no metric event emitted") +} + +fn assert_metric( + env: &Env, + topics: &Vec, + data: &Val, + metric_name: soroban_sdk::Symbol, + value: i128, +) { + let expected_topics: Vec = vec![ + env, + symbol_short!("metric").into_val(env), + contract_ids::WRAITH_NAMES.into_val(env), + metric_name.into_val(env), + ]; + assert_eq!(topics, &expected_topics); + + let (emitted_value, dimensions): (i128, Vec<(soroban_sdk::Symbol, Val)>) = data.into_val(env); + assert_eq!(emitted_value, value); + assert_eq!(dimensions.len(), 0, "names metrics carry no dimensions"); +} + +fn meta(env: &Env, byte: u8) -> Bytes { + Bytes::from_slice(env, &[byte; 64]) +} + +#[test] +fn register_emits_register_count_metric() { + let (env, client, owner) = setup(); + + client.register(&owner, &String::from_str(&env, "alice"), &meta(&env, 1)); + + let (topics, data) = only_metric_event(&env); + assert_metric(&env, &topics, &data, metric_names::REGISTER_COUNT, 1); +} + +#[test] +fn release_emits_release_count_metric() { + let (env, client, owner) = setup(); + let name = String::from_str(&env, "alice"); + + client.register(&owner, &name, &meta(&env, 1)); + client.release(&owner, &name); + + let (topics, data) = only_metric_event(&env); + assert_metric(&env, &topics, &data, metric_names::RELEASE_COUNT, 1); +} + +#[test] +fn extend_name_ttl_emits_renew_count_metric() { + let (env, client, owner) = setup(); + let name = String::from_str(&env, "alice"); + + client.register(&owner, &name, &meta(&env, 1)); + let extend_to = env.ledger().sequence() + 10_000; + client.extend_name_ttl(&name, &extend_to); + + let (topics, data) = only_metric_event(&env); + assert_metric(&env, &topics, &data, metric_names::RENEW_COUNT, 1); +} + +#[test] +fn bulk_renew_emits_renew_count_metric_carrying_batch_size() { + let (env, client, owner) = setup(); + + client.register(&owner, &String::from_str(&env, "alpha"), &meta(&env, 1)); + client.register(&owner, &String::from_str(&env, "beta"), &meta(&env, 2)); + + let names = vec![ + &env, + String::from_str(&env, "alpha"), + String::from_str(&env, "beta"), + ]; + let extend_to = env.ledger().sequence() + 10_000; + client.bulk_renew(&names, &extend_to); + + let (topics, data) = only_metric_event(&env); + assert_metric(&env, &topics, &data, metric_names::RENEW_COUNT, 2); +} + +#[test] +fn resolve_emits_hit_metric() { + let (env, client, owner) = setup(); + let name = String::from_str(&env, "alice"); + + client.register(&owner, &name, &meta(&env, 1)); + client.resolve(&name); + + let (topics, data) = only_metric_event(&env); + assert_metric(&env, &topics, &data, metric_names::RESOLVE_HIT_COUNT, 1); +} + +#[test] +fn resolve_emits_miss_metric_before_returning_not_found() { + let (env, client, _owner) = setup(); + + assert!(client + .try_resolve(&String::from_str(&env, "missing")) + .is_err()); + + let (topics, data) = only_metric_event(&env); + assert_metric(&env, &topics, &data, metric_names::RESOLVE_MISS_COUNT, 1); +} diff --git a/stellar/wraith-names/tests/names_bulk.rs b/stellar/wraith-names/tests/names_bulk.rs index df3baac..c38ae98 100644 --- a/stellar/wraith-names/tests/names_bulk.rs +++ b/stellar/wraith-names/tests/names_bulk.rs @@ -210,11 +210,16 @@ fn test_bulk_register_emits_per_name_events() { client.bulk_register(&owner, &names, &metas); - // Should have 2 per-name register events + 1 BulkRegistered event + // Should have 2 per-name register events + 2 per-name register metrics + // + 1 BulkRegistered event let events = env.events().all(); // Each event has 3 components: topics, data // We check total count - assert_eq!(events.len(), 3, "expected 2 register + 1 bulk_reg events"); + assert_eq!( + events.len(), + 5, + "expected 2 register + 2 register metrics + 1 bulk_reg events" + ); } /// 8. Happy path: bulk_renew extends TTL for multiple names. @@ -339,6 +344,10 @@ fn test_bulk_renew_emits_per_name_events() { client.bulk_renew(&names, &extend_to); let events = env.events().all(); - // 2 per-name extend events + 1 bulk_renew event - assert_eq!(events.len(), 3, "expected 2 extend + 1 blk_renew events"); + // 2 per-name extend events + 1 bulk_renew event + 1 batch renew metric + assert_eq!( + events.len(), + 4, + "expected 2 extend + 1 blk_renew + 1 renew metric events" + ); } diff --git a/stellar/wraith-names/tests/properties.rs b/stellar/wraith-names/tests/properties.rs index 0622b98..1fa086a 100644 --- a/stellar/wraith-names/tests/properties.rs +++ b/stellar/wraith-names/tests/properties.rs @@ -136,7 +136,7 @@ proptest! { } #[test] - fn successful_register_emits_one_event(name_value in valid_name_strategy(), meta in any::<[u8; 64]>()) { + fn successful_register_emits_domain_and_metric_events(name_value in valid_name_strategy(), meta in any::<[u8; 64]>()) { let env = env(); env.mock_all_auths(); let contract_id = env.register(WraithNamesContract, ()); @@ -147,7 +147,8 @@ proptest! { client.register(&owner, &name, &meta); - prop_assert_eq!(env.events().all().len(), 1); + // One `register` domain event followed by one wraith-metrics event. + prop_assert_eq!(env.events().all().len(), 2); } }