diff --git a/engine-core/src/core/control_plane.rs b/engine-core/src/core/control_plane.rs index 15184c7..04a93fb 100644 --- a/engine-core/src/core/control_plane.rs +++ b/engine-core/src/core/control_plane.rs @@ -45,6 +45,7 @@ const RESERVED_KEYS: &[Symbol] = &[ symbol_short!("SNAPC"), symbol_short!("SNAPL"), symbol_short!("OUTFLOWS"), + symbol_short!("TR_ADMIN"), symbol_short!("VERSION"), symbol_short!("VER_INIT"), symbol_short!("ZK_COUNT"), @@ -191,6 +192,12 @@ impl ControlPlane { } /// Store a governance proposal via the shared governance module. + /// + /// Governance already authenticates internally. Treasury mutations + /// (`schedule_outflow`, `execute_outflow`, `record_snapshot`) likewise + /// require an authenticated admin inside `crate::treasury`, so a future + /// ControlPlane wrapper for issue #178 must forward `caller` and cannot + /// bypass that check by omitting it at this layer. pub fn propose(env: Env, proposal: Proposal) -> u64 { crate::governance::propose(&env, proposal) } diff --git a/engine-core/src/treasury.rs b/engine-core/src/treasury.rs index dc1ecfd..29e15d1 100644 --- a/engine-core/src/treasury.rs +++ b/engine-core/src/treasury.rs @@ -7,10 +7,11 @@ use crate::event_struct::{ACT_REQUEST, ACT_SNAPSHOT, ACT_TRIGGERED, MOD_TREASURY use crate::event_utils::{publish_event, zero_hash}; use crate::types::{TreasurySnapshot, TriggerKind}; use soroban_sdk::{ - contracterror, contracttype, panic_with_error, symbol_short, Bytes, BytesN, Env, Map, Symbol, - Val, Vec, + contracterror, contracttype, panic_with_error, symbol_short, Address, Bytes, BytesN, Env, Map, + Symbol, Val, Vec, }; +const KEY_ADMIN: Symbol = symbol_short!("TR_ADMIN"); const KEY_SNAP_COUNTER: Symbol = symbol_short!("SNAPC"); const KEY_SNAP_LATEST: Symbol = symbol_short!("SNAPL"); const KEY_OUTFLOWS: Symbol = symbol_short!("OUTFLOWS"); @@ -45,6 +46,9 @@ pub enum TreasuryError { TimelockActive = 7, DuplicateOutflow = 8, ArithmeticOverflow = 9, + Unauthorized = 10, + NotInitialized = 11, + AlreadyInitialized = 12, } #[contracttype] @@ -57,7 +61,11 @@ pub struct TimelockedOutflow { pub executed: bool, } -pub fn init(env: &Env) { +pub fn init(env: &Env, admin: Address) { + if env.storage().instance().has(&KEY_ADMIN) { + panic_with_error!(env, TreasuryError::AlreadyInitialized); + } + env.storage().instance().set(&KEY_ADMIN, &admin); env.storage().instance().set(&KEY_SNAP_COUNTER, &0u64); env.storage().instance().set(&KEY_SNAP_LATEST, &0u64); env.storage() @@ -65,11 +73,28 @@ pub fn init(env: &Env) { .set(&KEY_OUTFLOWS, &Map::::new(env)); } +fn require_admin(env: &Env, caller: &Address) { + caller.require_auth(); + let admin: Address = env + .storage() + .instance() + .get(&KEY_ADMIN) + .unwrap_or_else(|| panic_with_error!(env, TreasuryError::NotInitialized)); + if caller != &admin { + panic_with_error!(env, TreasuryError::Unauthorized); + } +} + /// Queue a treasury outflow behind the mandatory 24-hour delay. -pub fn schedule_outflow(env: &Env, outflow_id: u64, amount: i128) -> u64 { +/// +/// Authorization is enforced in this module, not only at a future ControlPlane +/// wrapper (see issue #178). Wrappers must forward `caller`; they cannot omit +/// the check because `require_admin` lives here. +pub fn schedule_outflow(env: &Env, caller: &Address, outflow_id: u64, amount: i128) -> u64 { crate::non_reentrant!(env); assert_closed(env); + require_admin(env, caller); if amount <= 0 { panic_with_error!(env, TreasuryError::InvalidOutflowAmount); @@ -99,10 +124,15 @@ pub fn schedule_outflow(env: &Env, outflow_id: u64, amount: i128) -> u64 { } /// Mark an outflow executable only after its 24-hour time-lock has expired. -pub fn execute_outflow(env: &Env, outflow_id: u64) -> TimelockedOutflow { +/// +/// Authorization is enforced in this module, not only at a future ControlPlane +/// wrapper (see issue #178). Wrappers must forward `caller`; they cannot omit +/// the check because `require_admin` lives here. +pub fn execute_outflow(env: &Env, caller: &Address, outflow_id: u64) -> TimelockedOutflow { crate::non_reentrant!(env); assert_closed(env); + require_admin(env, caller); let mut outflows = load_outflows(env); let mut outflow = outflows @@ -134,12 +164,14 @@ pub fn get_outflow(env: &Env, outflow_id: u64) -> Option { } -/// Record a treasury snapshot and return its ID. - /// Record a treasury snapshot and return its monotonic snapshot id. - +/// +/// Authorization is enforced in this module, not only at a future ControlPlane +/// wrapper (see issue #178). Wrappers must forward `caller`; they cannot omit +/// the check because `require_admin` lives here. pub fn record_snapshot( env: &Env, + caller: &Address, total_balance: i128, account_count: u32, trigger: TriggerKind, @@ -148,6 +180,7 @@ pub fn record_snapshot( crate::non_reentrant!(env); assert_closed(env); + require_admin(env, caller); if total_balance < 0 { panic_with_error!(env, TreasuryError::InvalidBalance); @@ -278,7 +311,11 @@ fn make_snap_key(id: u64) -> TreasuryKey { #[cfg(test)] mod tests { use super::*; - use soroban_sdk::{contract, contractimpl, testutils::Ledger as _, Env, Map, Symbol}; + use soroban_sdk::{ + contract, contractimpl, + testutils::{Address as _, Ledger as _}, + Env, Map, Symbol, + }; #[contract] pub struct TestContract; @@ -286,71 +323,149 @@ mod tests { #[contractimpl] impl TestContract {} - fn with_treasury_env(run: impl FnOnce(&Env)) { + fn setup() -> (Env, Address, Address) { let env = Env::default(); + env.mock_all_auths(); let contract_id = env.register_contract(None, TestContract); - env.as_contract(&contract_id, || { - init(&env); - run(&env); - }); + let admin = Address::generate(&env); + env.as_contract(&contract_id, || init(&env, admin.clone())); + (env, contract_id, admin) + } + + fn setup_without_auth_mock() -> (Env, Address, Address) { + let env = Env::default(); + let contract_id = env.register_contract(None, TestContract); + let admin = Address::generate(&env); + env.as_contract(&contract_id, || init(&env, admin.clone())); + (env, contract_id, admin) } #[test] fn snapshot_creation_and_retrieval() { - with_treasury_env(|env| { - let ctx: Map = Map::new(env); - let id = record_snapshot(env, 1000, 5, TriggerKind::Deposit, ctx); + let (env, contract_id, admin) = setup(); + env.as_contract(&contract_id, || { + let ctx: Map = Map::new(&env); + let id = record_snapshot(&env, &admin, 1000, 5, TriggerKind::Deposit, ctx); assert_eq!(id, 1); - let snap = get_snapshot(env, 1).unwrap(); + let snap = get_snapshot(&env, 1).unwrap(); assert_eq!(snap.total_balance, 1000); - assert_eq!(snapshot_count(env), 1); + assert_eq!(snapshot_count(&env), 1); }); } #[test] fn snapshot_hash_verification() { - with_treasury_env(|env| { - let ctx: Map = Map::new(env); - record_snapshot(env, 500, 2, TriggerKind::Withdrawal, ctx); - let snap = get_snapshot(env, 1).unwrap(); - assert!(verify_snapshot(env, &snap)); + let (env, contract_id, admin) = setup(); + env.as_contract(&contract_id, || { + let ctx: Map = Map::new(&env); + record_snapshot(&env, &admin, 500, 2, TriggerKind::Withdrawal, ctx); + let snap = get_snapshot(&env, 1).unwrap(); + assert!(verify_snapshot(&env, &snap)); }); } #[test] -fn latest_snapshot_is_none_when_empty() { - with_treasury_env(|env| { - assert!(get_latest_snapshot(env).is_none()); - assert_eq!(snapshot_count(env), 0); - }); -} + fn latest_snapshot_is_none_when_empty() { + let (env, contract_id, _admin) = setup(); + env.as_contract(&contract_id, || { + assert!(get_latest_snapshot(&env).is_none()); + assert_eq!(snapshot_count(&env), 0); + }); + } #[test] #[should_panic] fn negative_balance_rejected() { - with_treasury_env(|env| { - let ctx: Map = Map::new(env); - record_snapshot(env, -1, 0, TriggerKind::Other, ctx); + let (env, contract_id, admin) = setup(); + env.as_contract(&contract_id, || { + let ctx: Map = Map::new(&env); + record_snapshot(&env, &admin, -1, 0, TriggerKind::Other, ctx); }); } #[test] #[should_panic] fn withdrawal_blocked_before_time_lock_expires() { - with_treasury_env(|env| { - schedule_outflow(env, 7, 1_000); - execute_outflow(env, 7); + let (env, contract_id, admin) = setup(); + env.as_contract(&contract_id, || { + schedule_outflow(&env, &admin, 7, 1_000); + }); + env.as_contract(&contract_id, || { + execute_outflow(&env, &admin, 7); }); } #[test] fn withdrawal_executes_after_time_lock_expires() { - with_treasury_env(|env| { - let unlock_at = schedule_outflow(env, 7, 1_000); - env.ledger().set_timestamp(unlock_at); - let outflow = execute_outflow(env, 7); + let (env, contract_id, admin) = setup(); + let unlock_at = env.as_contract(&contract_id, || schedule_outflow(&env, &admin, 7, 1_000)); + env.ledger().set_timestamp(unlock_at); + env.as_contract(&contract_id, || { + let outflow = execute_outflow(&env, &admin, 7); assert!(outflow.executed); assert_eq!(outflow.executable_at, unlock_at); }); } + + #[test] + #[should_panic] + fn schedule_outflow_rejects_unauthorized_caller() { + let (env, contract_id, _admin) = setup(); + let rogue = Address::generate(&env); + env.as_contract(&contract_id, || { + schedule_outflow(&env, &rogue, 1, 1_000); + }); + } + + #[test] + #[should_panic] + fn execute_outflow_rejects_unauthorized_caller() { + let (env, contract_id, admin) = setup(); + env.as_contract(&contract_id, || { + schedule_outflow(&env, &admin, 1, 1_000); + }); + let rogue = Address::generate(&env); + env.as_contract(&contract_id, || { + execute_outflow(&env, &rogue, 1); + }); + } + + #[test] + #[should_panic] + fn record_snapshot_rejects_unauthorized_caller() { + let (env, contract_id, _admin) = setup(); + let rogue = Address::generate(&env); + env.as_contract(&contract_id, || { + let ctx: Map = Map::new(&env); + record_snapshot(&env, &rogue, 1000, 1, TriggerKind::Manual, ctx); + }); + } + + #[test] + #[should_panic] + fn schedule_outflow_rejects_unauthenticated_caller() { + let (env, contract_id, admin) = setup_without_auth_mock(); + env.as_contract(&contract_id, || { + schedule_outflow(&env, &admin, 1, 1_000); + }); + } + + #[test] + #[should_panic] + fn execute_outflow_rejects_unauthenticated_caller() { + let (env, contract_id, admin) = setup_without_auth_mock(); + env.as_contract(&contract_id, || { + execute_outflow(&env, &admin, 1); + }); + } + + #[test] + #[should_panic] + fn record_snapshot_rejects_unauthenticated_caller() { + let (env, contract_id, admin) = setup_without_auth_mock(); + env.as_contract(&contract_id, || { + let ctx: Map = Map::new(&env); + record_snapshot(&env, &admin, 1000, 1, TriggerKind::Manual, ctx); + }); + } } diff --git a/engine-core/src/treasury_tests.rs b/engine-core/src/treasury_tests.rs index 14af2a5..e69dd69 100644 --- a/engine-core/src/treasury_tests.rs +++ b/engine-core/src/treasury_tests.rs @@ -5,7 +5,7 @@ mod tests { use crate::treasury; use crate::types::TriggerKind; - use soroban_sdk::{contract, contractimpl, Env, Map, Symbol, Val}; + use soroban_sdk::{contract, contractimpl, testutils::Address as _, Address, Env, Map, Symbol, Val}; #[contract] @@ -14,35 +14,39 @@ mod tests { #[contractimpl] impl TestContract {} - fn with_env(run: impl FnOnce(&Env)) { + fn setup() -> (Env, Address, Address) { let env = Env::default(); + env.mock_all_auths(); let contract_id = env.register_contract(None, TestContract); - env.as_contract(&contract_id, || { - treasury::init(&env); - run(&env); - }); + let admin = Address::generate(&env); + env.as_contract(&contract_id, || treasury::init(&env, admin.clone())); + (env, contract_id, admin) } #[test] fn records_and_retrieves_snapshot() { - with_env(|env| { - let ctx: Map = Map::new(env); - let id = treasury::record_snapshot(env, 1000, 5, TriggerKind::Deposit, ctx); - let snap = treasury::get_snapshot(env, id).unwrap(); + let (env, contract_id, admin) = setup(); + env.as_contract(&contract_id, || { + let ctx: Map = Map::new(&env); + let id = treasury::record_snapshot(&env, &admin, 1000, 5, TriggerKind::Deposit, ctx); + let snap = treasury::get_snapshot(&env, id).unwrap(); assert_eq!(snap.id, 1); assert_eq!(snap.total_balance, 1000); - assert!(treasury::verify_snapshot(env, &snap)); + assert!(treasury::verify_snapshot(&env, &snap)); }); } #[test] fn recent_snapshots_are_newest_first() { - with_env(|env| { - for i in 0..3 { - let ctx: Map = Map::new(env); - treasury::record_snapshot(env, 100 + i, 1, TriggerKind::Manual, ctx); - } - let ids = treasury::get_recent_snapshots(env, 2); + let (env, contract_id, admin) = setup(); + for i in 0..3 { + env.as_contract(&contract_id, || { + let ctx: Map = Map::new(&env); + treasury::record_snapshot(&env, &admin, 100 + i, 1, TriggerKind::Manual, ctx); + }); + } + env.as_contract(&contract_id, || { + let ids = treasury::get_recent_snapshots(&env, 2); assert_eq!(ids.get(0).unwrap(), 3); assert_eq!(ids.get(1).unwrap(), 2); }); @@ -51,9 +55,21 @@ mod tests { #[test] #[should_panic] fn negative_balance_is_rejected() { - with_env(|env| { - let ctx: Map = Map::new(env); - treasury::record_snapshot(env, -1, 0, TriggerKind::Other, ctx); + let (env, contract_id, admin) = setup(); + env.as_contract(&contract_id, || { + let ctx: Map = Map::new(&env); + treasury::record_snapshot(&env, &admin, -1, 0, TriggerKind::Other, ctx); + }); + } + + #[test] + #[should_panic] + fn record_snapshot_rejects_unauthorized_caller() { + let (env, contract_id, _admin) = setup(); + let rogue = Address::generate(&env); + env.as_contract(&contract_id, || { + let ctx: Map = Map::new(&env); + treasury::record_snapshot(&env, &rogue, 1000, 1, TriggerKind::Manual, ctx); }); } } diff --git a/engine-core/test_snapshots/treasury/tests/execute_outflow_rejects_unauthenticated_caller.1.json b/engine-core/test_snapshots/treasury/tests/execute_outflow_rejects_unauthenticated_caller.1.json new file mode 100644 index 0000000..1117267 --- /dev/null +++ b/engine-core/test_snapshots/treasury/tests/execute_outflow_rejects_unauthenticated_caller.1.json @@ -0,0 +1,166 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [] + ], + "ledger": { + "protocol_version": 21, + "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": { + "symbol": "OUTFLOWS" + }, + "val": { + "map": [] + } + }, + { + "key": { + "symbol": "SNAPC" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "SNAPL" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "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_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "auth": "invalid_action" + } + } + ], + "data": { + "vec": [ + { + "string": "Unauthorized function call for address" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "auth": "invalid_action" + } + } + ], + "data": { + "string": "escalating error to panic" + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/engine-core/test_snapshots/treasury/tests/execute_outflow_rejects_unauthorized_caller.1.json b/engine-core/test_snapshots/treasury/tests/execute_outflow_rejects_unauthorized_caller.1.json new file mode 100644 index 0000000..7a6f1b1 --- /dev/null +++ b/engine-core/test_snapshots/treasury/tests/execute_outflow_rejects_unauthorized_caller.1.json @@ -0,0 +1,348 @@ +{ + "generators": { + "address": 3, + "nonce": 0 + }, + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], + "ledger": { + "protocol_version": 21, + "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": { + "symbol": "OUTFLOWS" + }, + "val": { + "map": [ + { + "key": { + "u64": 1 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "executable_at" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "requested_at" + }, + "val": { + "u64": 0 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "SNAPC" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "SNAPL" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "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": "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_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": "EVENT" + }, + { + "symbol": "LOG" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "flags" + }, + "val": { + "u32": 2307 + } + }, + { + "key": { + "symbol": "hash" + }, + "val": { + "bytes": "0000000000000000000000000000000000000000000000000000000000000000" + } + }, + { + "key": { + "symbol": "value" + }, + "val": { + "u64": 1 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "contract": 10 + } + } + ], + "data": { + "vec": [ + { + "string": "failing with contract error" + }, + { + "u32": 10 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "contract": 10 + } + } + ], + "data": { + "string": "escalating error to panic" + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/engine-core/test_snapshots/treasury/tests/latest_snapshot_is_none_when_empty.1.json b/engine-core/test_snapshots/treasury/tests/latest_snapshot_is_none_when_empty.1.json index 00e3b7f..ace9908 100644 --- a/engine-core/test_snapshots/treasury/tests/latest_snapshot_is_none_when_empty.1.json +++ b/engine-core/test_snapshots/treasury/tests/latest_snapshot_is_none_when_empty.1.json @@ -1,9 +1,10 @@ { "generators": { - "address": 1, + "address": 2, "nonce": 0 }, "auth": [ + [], [] ], "ledger": { @@ -62,6 +63,14 @@ "val": { "u64": 0 } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } } ] } diff --git a/engine-core/test_snapshots/treasury/tests/negative_balance_rejected.1.json b/engine-core/test_snapshots/treasury/tests/negative_balance_rejected.1.json index 4041909..a9ef1c6 100644 --- a/engine-core/test_snapshots/treasury/tests/negative_balance_rejected.1.json +++ b/engine-core/test_snapshots/treasury/tests/negative_balance_rejected.1.json @@ -1,9 +1,11 @@ { "generators": { - "address": 1, + "address": 2, "nonce": 0 }, - "auth": [], + "auth": [ + [] + ], "ledger": { "protocol_version": 21, "sequence_number": 0, @@ -36,7 +38,40 @@ "executable": { "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }, - "storage": null + "storage": [ + { + "key": { + "symbol": "OUTFLOWS" + }, + "val": { + "map": [] + } + }, + { + "key": { + "symbol": "SNAPC" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "SNAPL" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] } } } @@ -46,6 +81,39 @@ 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": { diff --git a/engine-core/test_snapshots/treasury/tests/record_snapshot_rejects_unauthenticated_caller.1.json b/engine-core/test_snapshots/treasury/tests/record_snapshot_rejects_unauthenticated_caller.1.json new file mode 100644 index 0000000..1117267 --- /dev/null +++ b/engine-core/test_snapshots/treasury/tests/record_snapshot_rejects_unauthenticated_caller.1.json @@ -0,0 +1,166 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [] + ], + "ledger": { + "protocol_version": 21, + "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": { + "symbol": "OUTFLOWS" + }, + "val": { + "map": [] + } + }, + { + "key": { + "symbol": "SNAPC" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "SNAPL" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "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_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "auth": "invalid_action" + } + } + ], + "data": { + "vec": [ + { + "string": "Unauthorized function call for address" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "auth": "invalid_action" + } + } + ], + "data": { + "string": "escalating error to panic" + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/engine-core/test_snapshots/treasury/tests/record_snapshot_rejects_unauthorized_caller.1.json b/engine-core/test_snapshots/treasury/tests/record_snapshot_rejects_unauthorized_caller.1.json new file mode 100644 index 0000000..1c44dcc --- /dev/null +++ b/engine-core/test_snapshots/treasury/tests/record_snapshot_rejects_unauthorized_caller.1.json @@ -0,0 +1,199 @@ +{ + "generators": { + "address": 3, + "nonce": 0 + }, + "auth": [ + [] + ], + "ledger": { + "protocol_version": 21, + "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": { + "symbol": "OUTFLOWS" + }, + "val": { + "map": [] + } + }, + { + "key": { + "symbol": "SNAPC" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "SNAPL" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "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_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "contract": 10 + } + } + ], + "data": { + "vec": [ + { + "string": "failing with contract error" + }, + { + "u32": 10 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "contract": 10 + } + } + ], + "data": { + "string": "escalating error to panic" + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/engine-core/test_snapshots/treasury/tests/schedule_outflow_rejects_unauthenticated_caller.1.json b/engine-core/test_snapshots/treasury/tests/schedule_outflow_rejects_unauthenticated_caller.1.json new file mode 100644 index 0000000..1117267 --- /dev/null +++ b/engine-core/test_snapshots/treasury/tests/schedule_outflow_rejects_unauthenticated_caller.1.json @@ -0,0 +1,166 @@ +{ + "generators": { + "address": 2, + "nonce": 0 + }, + "auth": [ + [] + ], + "ledger": { + "protocol_version": 21, + "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": { + "symbol": "OUTFLOWS" + }, + "val": { + "map": [] + } + }, + { + "key": { + "symbol": "SNAPC" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "SNAPL" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "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_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "auth": "invalid_action" + } + } + ], + "data": { + "vec": [ + { + "string": "Unauthorized function call for address" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "auth": "invalid_action" + } + } + ], + "data": { + "string": "escalating error to panic" + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/engine-core/test_snapshots/treasury/tests/schedule_outflow_rejects_unauthorized_caller.1.json b/engine-core/test_snapshots/treasury/tests/schedule_outflow_rejects_unauthorized_caller.1.json new file mode 100644 index 0000000..1c44dcc --- /dev/null +++ b/engine-core/test_snapshots/treasury/tests/schedule_outflow_rejects_unauthorized_caller.1.json @@ -0,0 +1,199 @@ +{ + "generators": { + "address": 3, + "nonce": 0 + }, + "auth": [ + [] + ], + "ledger": { + "protocol_version": 21, + "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": { + "symbol": "OUTFLOWS" + }, + "val": { + "map": [] + } + }, + { + "key": { + "symbol": "SNAPC" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "SNAPL" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "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_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "contract": 10 + } + } + ], + "data": { + "vec": [ + { + "string": "failing with contract error" + }, + { + "u32": 10 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "contract": 10 + } + } + ], + "data": { + "string": "escalating error to panic" + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/engine-core/test_snapshots/treasury/tests/snapshot_creation_and_retrieval.1.json b/engine-core/test_snapshots/treasury/tests/snapshot_creation_and_retrieval.1.json index 9f08344..b4421a4 100644 --- a/engine-core/test_snapshots/treasury/tests/snapshot_creation_and_retrieval.1.json +++ b/engine-core/test_snapshots/treasury/tests/snapshot_creation_and_retrieval.1.json @@ -1,10 +1,25 @@ { "generators": { - "address": 1, + "address": 2, "nonce": 0 }, "auth": [ - [] + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] ], "ledger": { "protocol_version": 21, @@ -175,6 +190,14 @@ "val": { "u64": 1 } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } } ] } @@ -186,6 +209,39 @@ 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": { diff --git a/engine-core/test_snapshots/treasury/tests/snapshot_hash_verification.1.json b/engine-core/test_snapshots/treasury/tests/snapshot_hash_verification.1.json index 2479ffd..99e9c6f 100644 --- a/engine-core/test_snapshots/treasury/tests/snapshot_hash_verification.1.json +++ b/engine-core/test_snapshots/treasury/tests/snapshot_hash_verification.1.json @@ -1,10 +1,25 @@ { "generators": { - "address": 1, + "address": 2, "nonce": 0 }, "auth": [ - [] + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] ], "ledger": { "protocol_version": 21, @@ -175,6 +190,14 @@ "val": { "u64": 1 } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } } ] } @@ -186,6 +209,39 @@ 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": { diff --git a/engine-core/test_snapshots/treasury/tests/withdrawal_blocked_before_time_lock_expires.1.json b/engine-core/test_snapshots/treasury/tests/withdrawal_blocked_before_time_lock_expires.1.json index eecb34e..10c045d 100644 --- a/engine-core/test_snapshots/treasury/tests/withdrawal_blocked_before_time_lock_expires.1.json +++ b/engine-core/test_snapshots/treasury/tests/withdrawal_blocked_before_time_lock_expires.1.json @@ -1,9 +1,26 @@ { "generators": { - "address": 1, + "address": 2, "nonce": 0 }, - "auth": [], + "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] + ], "ledger": { "protocol_version": 21, "sequence_number": 0, @@ -36,7 +53,93 @@ "executable": { "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }, - "storage": null + "storage": [ + { + "key": { + "symbol": "OUTFLOWS" + }, + "val": { + "map": [ + { + "key": { + "u64": 7 + }, + "val": { + "map": [ + { + "key": { + "symbol": "amount" + }, + "val": { + "i128": { + "hi": 0, + "lo": 1000 + } + } + }, + { + "key": { + "symbol": "executable_at" + }, + "val": { + "u64": 86400 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 7 + } + }, + { + "key": { + "symbol": "requested_at" + }, + "val": { + "u64": 0 + } + } + ] + } + } + ] + } + }, + { + "key": { + "symbol": "SNAPC" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "SNAPL" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] } } } @@ -46,6 +149,72 @@ 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": { diff --git a/engine-core/test_snapshots/treasury/tests/withdrawal_executes_after_time_lock_expires.1.json b/engine-core/test_snapshots/treasury/tests/withdrawal_executes_after_time_lock_expires.1.json index 8cfc662..20bb3e2 100644 --- a/engine-core/test_snapshots/treasury/tests/withdrawal_executes_after_time_lock_expires.1.json +++ b/engine-core/test_snapshots/treasury/tests/withdrawal_executes_after_time_lock_expires.1.json @@ -1,10 +1,40 @@ { "generators": { - "address": 1, + "address": 2, "nonce": 0 }, "auth": [ - [] + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] ], "ledger": { "protocol_version": 21, @@ -115,6 +145,14 @@ "val": { "u64": 0 } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } } ] } @@ -126,6 +164,72 @@ 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": { diff --git a/engine-core/test_snapshots/treasury_tests/tests/negative_balance_is_rejected.1.json b/engine-core/test_snapshots/treasury_tests/tests/negative_balance_is_rejected.1.json index 4041909..a9ef1c6 100644 --- a/engine-core/test_snapshots/treasury_tests/tests/negative_balance_is_rejected.1.json +++ b/engine-core/test_snapshots/treasury_tests/tests/negative_balance_is_rejected.1.json @@ -1,9 +1,11 @@ { "generators": { - "address": 1, + "address": 2, "nonce": 0 }, - "auth": [], + "auth": [ + [] + ], "ledger": { "protocol_version": 21, "sequence_number": 0, @@ -36,7 +38,40 @@ "executable": { "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }, - "storage": null + "storage": [ + { + "key": { + "symbol": "OUTFLOWS" + }, + "val": { + "map": [] + } + }, + { + "key": { + "symbol": "SNAPC" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "SNAPL" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] } } } @@ -46,6 +81,39 @@ 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": { diff --git a/engine-core/test_snapshots/treasury_tests/tests/recent_snapshots_are_newest_first.1.json b/engine-core/test_snapshots/treasury_tests/tests/recent_snapshots_are_newest_first.1.json index 20b6bf4..243f7c1 100644 --- a/engine-core/test_snapshots/treasury_tests/tests/recent_snapshots_are_newest_first.1.json +++ b/engine-core/test_snapshots/treasury_tests/tests/recent_snapshots_are_newest_first.1.json @@ -1,9 +1,55 @@ { "generators": { - "address": 1, + "address": 2, "nonce": 0 }, "auth": [ + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ], [] ], "ledger": { @@ -401,6 +447,14 @@ "val": { "u64": 3 } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } } ] } @@ -412,6 +466,105 @@ 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": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "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": { diff --git a/engine-core/test_snapshots/treasury_tests/tests/record_snapshot_rejects_unauthorized_caller.1.json b/engine-core/test_snapshots/treasury_tests/tests/record_snapshot_rejects_unauthorized_caller.1.json new file mode 100644 index 0000000..1c44dcc --- /dev/null +++ b/engine-core/test_snapshots/treasury_tests/tests/record_snapshot_rejects_unauthorized_caller.1.json @@ -0,0 +1,199 @@ +{ + "generators": { + "address": 3, + "nonce": 0 + }, + "auth": [ + [] + ], + "ledger": { + "protocol_version": 21, + "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": { + "symbol": "OUTFLOWS" + }, + "val": { + "map": [] + } + }, + { + "key": { + "symbol": "SNAPC" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "SNAPL" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "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_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "contract": 10 + } + } + ], + "data": { + "vec": [ + { + "string": "failing with contract error" + }, + { + "u32": 10 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "contract": 10 + } + } + ], + "data": { + "string": "escalating error to panic" + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/engine-core/test_snapshots/treasury_tests/tests/records_and_retrieves_snapshot.1.json b/engine-core/test_snapshots/treasury_tests/tests/records_and_retrieves_snapshot.1.json index 9f08344..b4421a4 100644 --- a/engine-core/test_snapshots/treasury_tests/tests/records_and_retrieves_snapshot.1.json +++ b/engine-core/test_snapshots/treasury_tests/tests/records_and_retrieves_snapshot.1.json @@ -1,10 +1,25 @@ { "generators": { - "address": 1, + "address": 2, "nonce": 0 }, "auth": [ - [] + [], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "", + "args": [] + } + }, + "sub_invocations": [] + } + ] + ] ], "ledger": { "protocol_version": 21, @@ -175,6 +190,14 @@ "val": { "u64": 1 } + }, + { + "key": { + "symbol": "TR_ADMIN" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } } ] } @@ -186,6 +209,39 @@ 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": {