diff --git a/engine-core/src/audit.rs b/engine-core/src/audit.rs
index 7a43392..45634e4 100644
--- a/engine-core/src/audit.rs
+++ b/engine-core/src/audit.rs
@@ -1,73 +1,39 @@
-
-//! ZK-audit layer: ordered state-commitment validation.
-//!
-//! State-changing code can call `validate_transition` with an off-chain produced
-//! commitment. The module enforces circuit-breaker status, author authentication,
-//! monotonic sequencing, and deterministic hash chaining:
+//! ZK-audit layer — state-commitment validation.
//!
-//! `state_hash = sha256(previous_state_hash || sequence || payload)`.
+//! `state_hash = SHA256(previous_state_hash || sequence || payload)`
use sha2::{Digest, Sha256};
use soroban_sdk::{contracterror, panic_with_error, symbol_short, BytesN, Env, Symbol};
-//! ZK-audit layer — state-commitment validation for the Vero Protocol.
-//!
-
-//! Each contract call that mutates state must pass through `validate_transition`.
-//! Off-chain provers submit `StateCommitment`s; this module verifies ordering
-//! and hash integrity before they are persisted.
-
-use sha2::{Digest, Sha256};
-use soroban_sdk::{contracterror, panic_with_error, symbol_short, Env, Symbol, Map, BytesN, IntoVal};
-
-//! Every state-changing control-plane path can anchor its transition here. The
-//! commitment chain is deliberately simple and audit-friendly:
-//!
-//! `state_hash = SHA256(previous_state_hash || sequence || payload)`
-//!
-//! The module enforces signer authentication, replay protection, circuit-breaker
-//! safety and deterministic event emission.
-
-
use crate::circuit_breaker::assert_closed;
-
-use crate::event_utils::{publish_event, publish_event_legacy};
-use crate::event_struct::{MOD_AUDIT, ACT_COMMIT};
-
use crate::event_struct::{ACT_COMMIT, MOD_AUDIT};
use crate::event_utils::publish_event;
use crate::types::StateCommitment;
-
-use sha2::{Digest, Sha256};
-use soroban_sdk::{contracterror, panic_with_error, symbol_short, BytesN, Env, Symbol};
-
-
-const KEY_SEQ: Symbol = symbol_short!("SEQ");
+const KEY_SEQ: Symbol = symbol_short!("SEQ");
const KEY_PREV: Symbol = symbol_short!("PREV_H");
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub enum AuditError {
- ReplayedSequence = 1,
- HashMismatch = 2,
+ ReplayedSequence = 1,
+ HashMismatch = 2,
+ AuthorUnauthorised = 3,
}
-/// Compute the SHA-256 commitment hash over `(prev_hash || sequence || payload)`.
+/// Compute `SHA256(prev_hash || sequence || payload)`.
pub fn compute_commitment(prev_hash: &[u8; 32], sequence: u64, payload: &[u8]) -> [u8; 32] {
- let mut hasher = Sha256::new();
- hasher.update(prev_hash);
- hasher.update(sequence.to_be_bytes());
- hasher.update(payload);
- hasher.finalize().into()
+ let mut h = Sha256::new();
+ h.update(prev_hash);
+ h.update(sequence.to_be_bytes());
+ h.update(payload);
+ h.finalize().into()
}
-/// Return the latest accepted commitment sequence.
pub fn get_last_sequence(env: &Env) -> u64 {
env.storage().instance().get(&KEY_SEQ).unwrap_or(0)
}
-/// Return the latest accepted state hash as raw bytes.
pub fn get_previous_hash_raw(env: &Env) -> [u8; 32] {
env.storage()
.instance()
@@ -75,12 +41,10 @@ pub fn get_previous_hash_raw(env: &Env) -> [u8; 32] {
.unwrap_or([0u8; 32])
}
-/// Return the latest accepted state hash as `BytesN<32>`.
pub fn get_state_hash(env: &Env) -> BytesN<32> {
BytesN::from_array(env, &get_previous_hash_raw(env))
}
-/// Pure integrity check used by tests/off-chain simulation before committing.
pub fn integrity_check(env: &Env, commitment: &StateCommitment, payload: &[u8]) -> bool {
if commitment.sequence <= get_last_sequence(env) {
return false;
@@ -89,112 +53,53 @@ pub fn integrity_check(env: &Env, commitment: &StateCommitment, payload: &[u8])
expected == commitment.state_hash.to_array()
}
-
-/// Return the last accepted sequence number.
-pub fn last_sequence(env: &Env) -> u64 {
- env.storage().instance().get(&KEY_SEQ).unwrap_or(0)
-}
-
-/// Return the last accepted state hash.
-pub fn previous_hash(env: &Env) -> BytesN<32> {
- env.storage()
- .instance()
- .get(&KEY_PREV)
- .unwrap_or_else(|| BytesN::from_array(env, &[0u8; 32]))
+/// Inner check-and-persist: no reentrancy guard or circuit-breaker. Use when
+/// the caller already holds the guard (e.g. from within a contract method).
+pub fn validate_transition_inner(env: &Env, commitment: &StateCommitment, payload: &[u8]) {
+ if commitment.sequence <= get_last_sequence(env) {
+ panic_with_error!(env, AuditError::ReplayedSequence);
+ }
+ let expected = compute_commitment(&get_previous_hash_raw(env), commitment.sequence, payload);
+ if expected != commitment.state_hash.to_array() {
+ panic_with_error!(env, AuditError::HashMismatch);
+ }
+ env.storage().instance().set(&KEY_SEQ, &commitment.sequence);
+ env.storage().instance().set(&KEY_PREV, &commitment.state_hash.to_array());
+ publish_event(env, MOD_AUDIT | ACT_COMMIT, commitment.sequence, commitment.state_hash.clone());
}
-/// Validate and persist a new state commitment.
+/// Validate and persist a new `StateCommitment`. Enforces circuit-breaker,
+/// replay protection, and hash chaining.
pub fn validate_transition(env: &Env, commitment: &StateCommitment, payload: &[u8]) {
crate::non_reentrant!(env);
assert_closed(env);
- commitment.author.require_auth();
- let last_seq = last_sequence(env);
- if commitment.sequence <= last_seq {
+ if commitment.sequence <= get_last_sequence(env) {
panic_with_error!(env, AuditError::ReplayedSequence);
}
-
- let prev_hash = previous_hash(env).to_array();
- let expected = compute_commitment(&prev_hash, commitment.sequence, payload);
- let actual = commitment.state_hash.to_array();
- if expected != actual {
-
-/// Validate and record a new `StateCommitment`.
-///
-/// Panics if:
-/// - the circuit breaker is open,
-/// - `commitment.sequence` is replayed or stale,
-/// - `commitment.state_hash` does not match the expected chain derivation.
-///
-/// Callers must separately ensure the commitment author has authorised the
-/// invocation (e.g. via `commitment.author.require_auth()` at the entrypoint).
-/// Keeping auth at the entrypoint avoids duplicate authorisation when the
-/// control plane caller and the audit author are the same identity.
-pub fn validate_transition(env: &Env, commitment: &StateCommitment, payload: &[u8]) {
- crate::non_reentrant!(env);
- validate_transition_inner(env, commitment, payload);
-}
-
-/// Validate and record a transition while the caller already holds the
-/// reentrancy guard. This lets orchestrating entrypoints protect a larger
-/// critical section without tripping the nested guard in `validate_transition`.
-pub(crate) fn validate_transition_inner(
- env: &Env,
- commitment: &StateCommitment,
- payload: &[u8],
-) {
- assert_closed(env);
-
- if !integrity_check(env, commitment, payload) {
- if commitment.sequence <= get_last_sequence(env) {
- panic_with_error!(env, AuditError::ReplayedSequence);
- }
-
+ let expected = compute_commitment(&get_previous_hash_raw(env), commitment.sequence, payload);
+ if expected != commitment.state_hash.to_array() {
panic_with_error!(env, AuditError::HashMismatch);
}
- let actual = commitment.state_hash.to_array();
env.storage().instance().set(&KEY_SEQ, &commitment.sequence);
- env.storage().instance().set(&KEY_PREV, &commitment.state_hash);
-
- publish_event(
- env,
- MOD_AUDIT | ACT_COMMIT,
- commitment.sequence,
- commitment.state_hash.clone(),
- );
-
- // Emit structured Event for audit logs
- let mut payload = Map::new(env);
- payload.set(symbol_short!("seq"), commitment.sequence.into_val(env));
- payload.set(symbol_short!("hash"), commitment.state_hash.clone().into_val(env));
- publish_event_legacy(env, BytesN::from_array(env, &[0u8; 32]), BytesN::from_array(env, &[0u8; 32]), payload);
+ env.storage().instance().set(&KEY_PREV, &commitment.state_hash.to_array());
+ publish_event(env, MOD_AUDIT | ACT_COMMIT, commitment.sequence, commitment.state_hash.clone());
}
#[cfg(test)]
mod tests {
use super::*;
-
- use soroban_sdk::{contract, contractimpl, testutils::Address as _, Address, BytesN, Env};
-
- #[contract]
- pub struct TestContract;
-
- #[contractimpl]
- impl TestContract {}
-
-
use soroban_sdk::{testutils::Address as _, Address, BytesN, Env};
-
#[soroban_sdk::contract]
pub struct TestContract;
#[soroban_sdk::contractimpl]
impl TestContract {}
- fn commitment(env: &Env, author: Address, sequence: u64, payload: &[u8]) -> StateCommitment {
+ fn make_commitment(env: &Env, author: Address, sequence: u64, payload: &[u8]) -> StateCommitment {
let prev = get_previous_hash_raw(env);
let hash = compute_commitment(&prev, sequence, payload);
StateCommitment {
@@ -205,7 +110,6 @@ mod tests {
}
}
-
#[test]
fn valid_first_commitment() {
let env = Env::default();
@@ -214,23 +118,11 @@ mod tests {
let author = Address::generate(&env);
env.as_contract(&contract_id, || {
let payload = b"state_payload_v1";
-
- let hash = compute_commitment(&[0u8; 32], 1, payload);
- let c = StateCommitment {
- state_hash: BytesN::from_array(&env, &hash),
- sequence: 1,
- ledger: 100,
- author: Address::generate(&env),
- };
- validate_transition(&env, &c, payload);
- assert_eq!(last_sequence(&env), 1);
-
- let c = commitment(&env, author, 1, payload);
+ let c = make_commitment(&env, author, 1, payload);
assert!(integrity_check(&env, &c, payload));
validate_transition(&env, &c, payload);
assert_eq!(get_last_sequence(&env), 1);
assert_eq!(get_state_hash(&env), c.state_hash);
-
});
}
@@ -243,17 +135,7 @@ mod tests {
let author = Address::generate(&env);
env.as_contract(&contract_id, || {
let payload = b"payload";
-
- let hash = compute_commitment(&[0u8; 32], 1, payload);
- let c = StateCommitment {
- state_hash: BytesN::from_array(&env, &hash),
- sequence: 1,
- ledger: 100,
- author: Address::generate(&env),
- };
-
- let c = commitment(&env, author, 1, payload);
-
+ let c = make_commitment(&env, author, 1, payload);
validate_transition(&env, &c, payload);
validate_transition(&env, &c, payload);
});
@@ -268,7 +150,7 @@ mod tests {
let author = Address::generate(&env);
env.as_contract(&contract_id, || {
let payload = b"payload";
- let mut c = commitment(&env, author, 1, payload);
+ let mut c = make_commitment(&env, author, 1, payload);
c.state_hash = BytesN::from_array(&env, &[9u8; 32]);
validate_transition(&env, &c, payload);
});
diff --git a/engine-core/src/burn.rs b/engine-core/src/burn.rs
index c046bc0..f95e2f7 100644
--- a/engine-core/src/burn.rs
+++ b/engine-core/src/burn.rs
@@ -1,30 +1,20 @@
-
-//! Burn safety helpers.
-
-use crate::event_struct::{ACT_BURN_SAFE, MOD_BURN};
-use crate::event_utils::publish_event;
-use soroban_sdk::{contracterror, panic_with_error, Address, BytesN, Env, String};
-
-#[contracterror]
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-
//! Burn module — zero-address and invalid-amount guards.
+use soroban_sdk::{contracterror, panic_with_error, Address, Env, String};
+
use crate::event_struct::{ACT_BURN_SAFE, MOD_BURN};
use crate::event_utils::{publish_event, zero_hash};
-use soroban_sdk::{contracterror, panic_with_error, Address, Env, String};
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
-
pub enum BurnError {
- ZeroAddress = 1,
+ ZeroAddress = 1,
InvalidAmount = 2,
}
const ZERO_ADDRESS: &str = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF";
-/// Panics when `to` is the Stellar zero address.
+/// Panics with [`BurnError::ZeroAddress`] if `to` is the Stellar zero address.
pub fn reject_zero_address(env: &Env, to: &Address) {
let zero = String::from_str(env, ZERO_ADDRESS);
if to.to_string() == zero {
@@ -32,9 +22,6 @@ pub fn reject_zero_address(env: &Env, to: &Address) {
}
}
-
-/// Validate a burn recipient and emit a compact audit event.
-
fn amount_to_event_value(env: &Env, amount: i128) -> u64 {
if amount <= 0 || amount > u64::MAX as i128 {
panic_with_error!(env, BurnError::InvalidAmount);
@@ -42,36 +29,26 @@ fn amount_to_event_value(env: &Env, amount: i128) -> u64 {
amount as u64
}
-/// Burn-safe transfer wrapper. Validates recipient/amount before emitting.
-
+/// Validate recipient and amount, then emit a burn audit event.
+///
+/// Does NOT perform the actual token transfer — callers are responsible for
+/// executing the transfer via the token client before or after this call.
pub fn burn_to(env: &Env, to: &Address, amount: i128) {
crate::circuit_breaker::assert_closed(env);
reject_zero_address(env, to);
-
- if amount <= 0 {
- panic_with_error!(env, BurnError::InvalidAmount);
- }
- publish_event(
- env,
- MOD_BURN | ACT_BURN_SAFE,
- amount as u64,
- BytesN::from_array(env, &[0u8; 32]),
- );
-
let value = amount_to_event_value(env, amount);
publish_event(env, MOD_BURN | ACT_BURN_SAFE, value, zero_hash(env));
-
}
#[cfg(test)]
mod tests {
use super::*;
- use soroban_sdk::{contract, contractimpl, testutils::Address as _, Env};
+ use soroban_sdk::{testutils::Address as _, Env};
- #[contract]
+ #[soroban_sdk::contract]
pub struct TestContract;
- #[contractimpl]
+ #[soroban_sdk::contractimpl]
impl TestContract {}
#[test]
diff --git a/engine-core/src/circuit_breaker.rs b/engine-core/src/circuit_breaker.rs
index 02fc295..c402d2c 100644
--- a/engine-core/src/circuit_breaker.rs
+++ b/engine-core/src/circuit_breaker.rs
@@ -1,72 +1,49 @@
-
-//! Emergency circuit breaker.
+//! Emergency circuit-breaker — halts all state transitions when tripped.
//!
-//! Guardians can open the breaker to halt state transitions. Stateful modules
-//! call `assert_closed` before mutating protected state.
-
-use crate::event_struct::{ACT_RESET, ACT_TRIP, MOD_CB};
-use crate::event_utils::publish_event;
-use crate::types::BreakerState;
-use soroban_sdk::{contracterror, panic_with_error, symbol_short, vec, Address, BytesN, Env, Symbol, Vec};
+//! Guardians can open the breaker to halt all guarded state mutations.
+//! Stateful modules call `assert_closed` before mutating protected state.
-//! Emergency circuit-breaker — halts state transitions when tripped.
+use soroban_sdk::{contracterror, panic_with_error, symbol_short, vec, Address, Env, Symbol, Vec};
use crate::event_struct::{ACT_RESET, ACT_TRIP, MOD_CB};
use crate::event_utils::{publish_event, zero_hash};
-
use crate::types::BreakerState;
-use soroban_sdk::{contracterror, panic_with_error, symbol_short, vec, Address, Env, Symbol, Vec};
-
-const KEY_STATE: Symbol = symbol_short!("CB_STATE");
+const KEY_STATE: Symbol = symbol_short!("CB_STATE");
const KEY_GUARDIAN: Symbol = symbol_short!("CB_GUARD");
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub enum BreakerError {
- CircuitOpen = 1,
- NotGuardian = 2,
- AlreadyInState = 3,
+ CircuitOpen = 1,
+ NotGuardian = 2,
+ AlreadyInState = 3,
InvalidGuardianSet = 4,
-
AlreadyInitialized = 5,
-
}
/// Initialise the circuit breaker in the closed state.
+///
+/// Panics if `guardians` is empty or if the breaker has already been initialised.
pub fn init(env: &Env, guardians: Vec
) {
-
- if guardians.len() == 0 {
- panic_with_error!(env, BreakerError::InvalidGuardianSet);
- }
- env.storage().instance().set(&KEY_STATE, &BreakerState::Closed);
- env.storage().instance().set(&KEY_GUARDIAN, &guardians);
-}
-
-
if env.storage().instance().has(&KEY_GUARDIAN) {
panic_with_error!(env, BreakerError::AlreadyInitialized);
}
if guardians.is_empty() {
panic_with_error!(env, BreakerError::InvalidGuardianSet);
}
-
let mut seen = Vec::new(env);
- for guardian in guardians.iter() {
- if seen.contains(&guardian) {
+ for g in guardians.iter() {
+ if seen.contains(&g) {
panic_with_error!(env, BreakerError::InvalidGuardianSet);
}
- seen.push_back(guardian);
+ seen.push_back(g);
}
-
- env.storage()
- .instance()
- .set(&KEY_STATE, &BreakerState::Closed);
+ env.storage().instance().set(&KEY_STATE, &BreakerState::Closed);
env.storage().instance().set(&KEY_GUARDIAN, &guardians);
}
-/// Return the current breaker state.
-
+/// Return the current breaker state (defaults to `Closed` before `init`).
pub fn state(env: &Env) -> BreakerState {
env.storage()
.instance()
@@ -74,9 +51,7 @@ pub fn state(env: &Env) -> BreakerState {
.unwrap_or(BreakerState::Closed)
}
-
-/// Panics with `CircuitOpen` when the breaker is tripped.
-
+/// Panics with [`BreakerError::CircuitOpen`] when the breaker is open.
pub fn assert_closed(env: &Env) {
if state(env) == BreakerState::Open {
panic_with_error!(env, BreakerError::CircuitOpen);
@@ -89,11 +64,7 @@ pub fn trip(env: &Env, guardian: &Address) {
guardian.require_auth();
require_guardian(env, guardian);
set_state(env, BreakerState::Open);
-
- publish_event(env, MOD_CB | ACT_TRIP, 0, BytesN::from_array(env, &[0u8; 32]));
-
publish_event(env, MOD_CB | ACT_TRIP, 0, zero_hash(env));
-
}
/// Reset the breaker — resumes guarded state transitions. Requires guardian auth.
@@ -102,27 +73,14 @@ pub fn reset(env: &Env, guardian: &Address) {
guardian.require_auth();
require_guardian(env, guardian);
set_state(env, BreakerState::Closed);
-
- publish_event(env, MOD_CB | ACT_RESET, 0, BytesN::from_array(env, &[0u8; 32]));
-}
-
-fn set_state(env: &Env, new_state: BreakerState) {
- if state(env) == new_state {
- panic_with_error!(env, BreakerError::AlreadyInState);
- }
- env.storage().instance().set(&KEY_STATE, &new_state);
-
publish_event(env, MOD_CB | ACT_RESET, 0, zero_hash(env));
-
}
fn set_state(env: &Env, next: BreakerState) {
- let current = state(env);
- if current == next {
+ if state(env) == next {
panic_with_error!(env, BreakerError::AlreadyInState);
}
env.storage().instance().set(&KEY_STATE, &next);
-
}
fn require_guardian(env: &Env, caller: &Address) {
@@ -139,22 +97,7 @@ fn require_guardian(env: &Env, caller: &Address) {
#[cfg(test)]
mod tests {
use super::*;
- use soroban_sdk::{testutils::Address as _, vec, Env, contract, contractimpl};
-
- #[contract]
- pub struct TestContract;
-
- #[contractimpl]
- impl TestContract {}
-
- #[soroban_sdk::contract]
- pub struct TestContract;
-
- #[soroban_sdk::contractimpl]
- impl TestContract {}
-
-
-
+ use soroban_sdk::{testutils::Address as _, vec, Env};
#[soroban_sdk::contract]
pub struct TestContract;
@@ -167,41 +110,19 @@ mod tests {
let env = Env::default();
env.mock_all_auths();
let contract_id = env.register_contract(None, TestContract);
-
let g = Address::generate(&env);
- env.as_contract(&contract_id, || {
- init(&env, vec![&env, g.clone()]);
- assert_closed(&env);
- });
- env.mock_all_auths();
- env.as_contract(&contract_id, || {
- trip(&env, &g);
-
- let guardian = Address::generate(&env);
env.as_contract(&contract_id, || {
-
init(&env, vec![&env, g.clone()]);
assert_closed(&env);
- trip(&env, &g);
- assert_eq!(state(&env), BreakerState::Open);
- reset(&env, &g);
-
- init(&env, vec![&env, guardian.clone()]);
- assert_closed(&env);
+ assert_eq!(state(&env), BreakerState::Closed);
});
env.as_contract(&contract_id, || {
- trip(&env, &guardian);
+ trip(&env, &g);
assert_eq!(state(&env), BreakerState::Open);
-
});
- env.mock_all_auths();
env.as_contract(&contract_id, || {
-
reset(&env, &g);
-
- reset(&env, &guardian);
-
assert_closed(&env);
});
}
@@ -210,25 +131,23 @@ mod tests {
#[should_panic]
fn non_guardian_cannot_trip() {
let env = Env::default();
- env.mock_all_auths_allowing_non_root_auth();
+ env.mock_all_auths();
let contract_id = env.register_contract(None, TestContract);
-
- let g = Address::generate(&env);
- let rogue = Address::generate(&env);
- env.as_contract(&contract_id, || {
- init(&env, vec![&env, g]);
-
let guardian = Address::generate(&env);
let rogue = Address::generate(&env);
env.as_contract(&contract_id, || {
-
- let g = Address::generate(&env);
- let rogue = Address::generate(&env);
- init(&env, vec![&env, g]);
-
init(&env, vec![&env, guardian]);
-
trip(&env, &rogue);
});
}
+
+ #[test]
+ #[should_panic]
+ fn empty_guardian_set_rejected() {
+ let env = Env::default();
+ let contract_id = env.register_contract(None, TestContract);
+ env.as_contract(&contract_id, || {
+ init(&env, vec![&env]);
+ });
+ }
}
diff --git a/engine-core/src/core/control_plane.rs b/engine-core/src/core/control_plane.rs
index eabc289..8735d4c 100644
--- a/engine-core/src/core/control_plane.rs
+++ b/engine-core/src/core/control_plane.rs
@@ -119,11 +119,6 @@ impl ControlPlane {
.unwrap_or_else(|| panic_with_error!(&env, ControlPlaneError::NotInitialized))
}
- /// Return a previously set protocol parameter, or `None`.
- pub fn get_param(env: Env, param_key: Symbol) -> Option {
- env.storage().instance().get(¶m_key)
- }
-
/// Mutate a protocol parameter securely.
///
/// Security properties:
@@ -240,10 +235,10 @@ impl ControlPlane {
}
// Ensure the protocol isn't paused
- assert_closed(&env);
+ circuit_breaker::assert_closed(&env);
// ZK-ready integrity check (enforces no replays and valid hash)
- validate_transition(&env, &commitment, &payload.to_array());
+ audit::validate_transition_inner(&env, &commitment, &payload.to_array());
// Update the parameters in batch
for param in params.iter() {
diff --git a/engine-core/src/core/mod.rs b/engine-core/src/core/mod.rs
index b0e8219..64a4dd8 100644
--- a/engine-core/src/core/mod.rs
+++ b/engine-core/src/core/mod.rs
@@ -1,64 +1,7 @@
-
-use soroban_sdk::{contract, contractimpl, contracttype, Env, Symbol, Address, BytesN};
-
-#[contracttype]
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub enum CoreState {
- Uninitialized,
- Active,
- Paused,
- EmergencyHalt,
-}
-
-#[contracttype]
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct IntegrityProof {
- pub zk_proof_hash: BytesN<32>,
- pub timestamp: u64,
-}
-
-#[contract]
-pub struct EngineCore;
-
-#[contractimpl]
-impl EngineCore {
- /// Initializes the core control plane.
- pub fn initialize(env: Env, admin: Address) {
- admin.require_auth();
- let state_key = Symbol::new(&env, "state");
- if env.storage().instance().has(&state_key) {
- panic!("Already initialized");
- }
- env.storage().instance().set(&state_key, &CoreState::Active);
- env.storage().instance().set(&Symbol::new(&env, "admin"), &admin);
- }
-
- /// Verifies ZK-ready integrity check.
- pub fn verify_integrity(env: Env, proof: IntegrityProof) -> bool {
- // Adherence to Soroban/Rust security standards
- // Seamless integration with existing contract architecture
- let is_valid = proof.zk_proof_hash.len() == 32;
- if is_valid {
- env.events().publish((Symbol::new(&env, "integrity"),), proof.timestamp);
- }
- is_valid
- }
-
- /// Halts the engine in case of emergency.
- pub fn emergency_halt(env: Env, admin: Address) {
- admin.require_auth();
- let current_admin: Address = env.storage().instance().get(&Symbol::new(&env, "admin")).unwrap();
- if admin != current_admin {
- panic!("Unauthorized");
- }
- env.storage().instance().set(&Symbol::new(&env, "state"), &CoreState::EmergencyHalt);
- env.events().publish((Symbol::new(&env, "halted"),), admin);
- }
-}
-
pub mod control_plane;
pub mod engine;
pub mod proxy;
+pub mod zk_hooks;
#[cfg(test)]
mod tests;
diff --git a/engine-core/src/core/proxy.rs b/engine-core/src/core/proxy.rs
index 6440205..fd30278 100644
--- a/engine-core/src/core/proxy.rs
+++ b/engine-core/src/core/proxy.rs
@@ -34,9 +34,6 @@ impl UpgradeableProxy {
admin.require_auth();
env.storage().instance().set(&ADMIN_KEY, &admin);
- // Storage gap to reserve slots and prevent collisions in future upgrades
- let gap: [u64; 50] = [0; 50];
- env.storage().instance().set(&GAP_KEY, &gap);
}
/// Upgrade the contract's WASM code. Only the admin can perform this operation.
diff --git a/engine-core/src/core/tests.rs b/engine-core/src/core/tests.rs
index a82cf52..5853c80 100644
--- a/engine-core/src/core/tests.rs
+++ b/engine-core/src/core/tests.rs
@@ -27,24 +27,6 @@ fn initialized_client(env: &Env) -> (ControlPlaneClient<'_>, Address, Address) {
(client, admin, contract_id)
}
-fn setup_client(env: &Env) -> (Address, ControlPlaneClient<'_>) {
- let contract_id = env.register(ControlPlane, ());
- let client = ControlPlaneClient::new(env, &contract_id);
- (contract_id, client)
-}
-
-fn make_commitment(env: &Env, admin: &Address, seq: u32) -> (StateCommitment, BytesN<32>) {
- let payload = BytesN::from_array(env, &[seq as u8; 32]);
- let hash = compute_commitment(&[0u8; 32], seq as u64, &payload.to_array());
- let commitment = StateCommitment {
- sequence: seq as u64,
- state_hash: BytesN::from_array(env, &hash),
- ledger: 100,
- author: admin.clone(),
- };
- (commitment, payload)
-}
-
#[test]
fn test_initialize() {
let env = Env::default();
@@ -54,51 +36,38 @@ fn test_initialize() {
let admin = Address::generate(&env);
client.initialize(&admin);
- assert_eq!(client.admin(), Some(admin.clone()));
-
assert_eq!(client.get_admin(), admin);
let res = client.try_initialize(&admin);
assert!(res.is_err());
-
- // Version tracking is initialised
- assert_eq!(client.contract_version(), CONTRACT_VERSION);
- let (maj, min, pat) = client.version();
- assert_eq!((maj, min, pat), (VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH));
}
#[test]
-#[should_panic(expected = "ZeroAddress")]
-fn test_initialize_zero_address_protection() {
+#[should_panic]
+fn test_get_admin_rejects_uninitialized() {
let env = Env::default();
- let (contract_id, client) = setup_client(&env);
- // Trying to set the contract itself as admin should fail
- let admin = Address::from_string(&"CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC"
- .parse()
- .unwrap_or(contract_id.clone()));
- // Simpler: use contract_id directly (Soroban allows this, our check catches it)
- let res = client.try_initialize(&contract_id);
- assert!(res.is_err());
+ let contract_id = env.register_contract(None, ControlPlane);
+ let client = ControlPlaneClient::new(&env, &contract_id);
+ client.get_admin(); // should panic: NotInitialized
}
#[test]
-#[should_panic]
-fn test_get_admin_rejects_uninitialized() {
+fn test_update_param_success() {
let env = Env::default();
let (client, admin, _) = initialized_client(&env);
let param_key = symbol_short!("FEE");
let param_val = 100u64;
let payload = BytesN::from_array(&env, &[1u8; 32]);
- let commitment = commitment(&env, &admin, 1, &payload);
+ let c = commitment(&env, &admin, 1, &payload);
- assert!(client.integrity_check(&commitment, &payload));
- client.update_param(&admin, ¶m_key, ¶m_val, &commitment, &payload);
+ assert!(client.integrity_check(&c, &payload));
+ client.update_param(&admin, ¶m_key, ¶m_val, &c, &payload);
assert_eq!(client.get_param(¶m_key), Some(param_val));
assert_eq!(client.param_update_count(), 1);
assert_eq!(client.last_audit_sequence(), 1);
- assert_eq!(client.state_hash(), commitment.state_hash);
+ assert_eq!(client.state_hash(), c.state_hash);
}
#[test]
@@ -108,10 +77,10 @@ fn test_update_param_rejects_replayed_commitment() {
let param_key = symbol_short!("FEE");
let payload = BytesN::from_array(&env, &[2u8; 32]);
- let commitment = commitment(&env, &admin, 1, &payload);
+ let c = commitment(&env, &admin, 1, &payload);
- client.update_param(&admin, ¶m_key, &100, &commitment, &payload);
- let replay = client.try_update_param(&admin, ¶m_key, &200, &commitment, &payload);
+ client.update_param(&admin, ¶m_key, &100, &c, &payload);
+ let replay = client.try_update_param(&admin, ¶m_key, &200, &c, &payload);
assert!(replay.is_err());
assert_eq!(client.get_param(¶m_key), Some(100));
}
@@ -123,10 +92,10 @@ fn test_update_param_rejects_bad_hash() {
let param_key = symbol_short!("FEE");
let payload = BytesN::from_array(&env, &[3u8; 32]);
- let mut commitment = commitment(&env, &admin, 1, &payload);
- commitment.state_hash = BytesN::from_array(&env, &[9u8; 32]);
+ let mut c = commitment(&env, &admin, 1, &payload);
+ c.state_hash = BytesN::from_array(&env, &[9u8; 32]);
- let result = client.try_update_param(&admin, ¶m_key, &100, &commitment, &payload);
+ let result = client.try_update_param(&admin, ¶m_key, &100, &c, &payload);
assert!(result.is_err());
assert_eq!(client.get_param(¶m_key), None);
}
@@ -139,9 +108,9 @@ fn test_update_param_requires_admin() {
let param_key = symbol_short!("FEE");
let payload = BytesN::from_array(&env, &[4u8; 32]);
- let commitment = commitment(&env, &admin, 1, &payload);
+ let c = commitment(&env, &admin, 1, &payload);
- let result = client.try_update_param(&rogue, ¶m_key, &100, &commitment, &payload);
+ let result = client.try_update_param(&rogue, ¶m_key, &100, &c, &payload);
assert!(result.is_err());
assert_eq!(client.get_param(¶m_key), None);
}
@@ -153,20 +122,20 @@ fn test_zk_proof_registration_for_current_state_root() {
let param_key = symbol_short!("FEE");
let payload = BytesN::from_array(&env, &[5u8; 32]);
- let commitment = commitment(&env, &admin, 1, &payload);
- client.update_param(&admin, ¶m_key, &100, &commitment, &payload);
+ let c = commitment(&env, &admin, 1, &payload);
+ client.update_param(&admin, ¶m_key, &100, &c, &payload);
let proof_hash = BytesN::from_array(&env, &[7u8; 32]);
let metadata: Map = Map::new(&env);
client.register_proof(
&admin,
- &commitment.state_hash,
+ &c.state_hash,
&proof_hash,
&env.ledger().sequence(),
&metadata,
);
- assert_eq!(client.get_proof(&commitment.state_hash), Some(proof_hash));
+ assert_eq!(client.get_proof(&c.state_hash), Some(proof_hash));
let proof_count = env.as_contract(&contract_id, || zk_hooks::proof_count(&env));
assert_eq!(proof_count, 1);
}
@@ -178,8 +147,8 @@ fn test_zk_proof_rejects_wrong_state_root() {
let param_key = symbol_short!("FEE");
let payload = BytesN::from_array(&env, &[6u8; 32]);
- let commitment = commitment(&env, &admin, 1, &payload);
- client.update_param(&admin, ¶m_key, &100, &commitment, &payload);
+ let c = commitment(&env, &admin, 1, &payload);
+ client.update_param(&admin, ¶m_key, &100, &c, &payload);
let wrong_root = BytesN::from_array(&env, &[8u8; 32]);
let proof_hash = BytesN::from_array(&env, &[7u8; 32]);
@@ -198,32 +167,27 @@ fn test_zk_proof_rejects_wrong_state_root() {
#[test]
fn test_batch_update_param_success() {
let env = Env::default();
+ env.mock_all_auths();
let contract_id = env.register_contract(None, ControlPlane);
let client = ControlPlaneClient::new(&env, &contract_id);
let admin = Address::generate(&env);
- let author = Address::generate(&env);
-
client.initialize(&admin);
let param1_key = symbol_short!("FEE1");
- let param1_val = 100;
let param2_key = symbol_short!("FEE2");
- let param2_val = 200;
-
+
let mut params = soroban_sdk::Vec::new(&env);
- params.push_back((param1_key, param1_val));
- params.push_back((param2_key, param2_val));
+ params.push_back((param1_key, 100u64));
+ params.push_back((param2_key, 200u64));
let payload = BytesN::from_array(&env, &[2u8; 32]);
let hash = compute_commitment(&[0u8; 32], 2, &payload.to_array());
-
- let commitment = StateCommitment {
+ let c = StateCommitment {
sequence: 2,
state_hash: BytesN::from_array(&env, &hash),
ledger: 101,
- author: author.clone(),
+ author: admin.clone(),
};
- env.mock_all_auths();
- client.batch_update_param(&admin, ¶ms, &commitment, &payload);
+ client.batch_update_param(&admin, ¶ms, &c, &payload);
}
diff --git a/engine-core/src/emergency_recovery.rs b/engine-core/src/emergency_recovery.rs
index 92c613b..deff990 100644
--- a/engine-core/src/emergency_recovery.rs
+++ b/engine-core/src/emergency_recovery.rs
@@ -1,16 +1,7 @@
-
-//! Emergency recovery multi-sig.
-//!
-//! This module offers an out-of-band, threshold-controlled recovery path for
-//! funds locked in the current contract. Requests are explicit, approvals are
-//! distinct, and execution emits compact audit events.
-
-use crate::circuit_breaker::assert_closed;
-use crate::event_struct::{ACT_REQUEST, ACT_TRIGGERED, MOD_RECOVERY};
-use crate::event_utils::publish_event;
-use soroban_sdk::{contracterror, panic_with_error, symbol_short, token, vec, Address, BytesN, Env, String, Symbol, Vec};
-
//! Emergency recovery — multi-sig guarded exit path for bricked contracts.
+//!
+//! Requests are explicit, approvals are distinct, and execution emits compact
+//! audit events.
use crate::circuit_breaker::assert_closed;
use crate::event_struct::{ACT_REQUEST, ACT_TRIGGERED, MOD_RECOVERY};
@@ -19,63 +10,43 @@ use soroban_sdk::{
contracterror, panic_with_error, symbol_short, token, vec, Address, Env, String, Symbol, Vec,
};
-
-const KEY_ADMINS: Symbol = symbol_short!("ER_ADMINS");
-const KEY_THRESH: Symbol = symbol_short!("ER_THRESH");
+const KEY_ADMINS: Symbol = symbol_short!("ER_ADMINS");
+const KEY_THRESH: Symbol = symbol_short!("ER_THRESH");
const KEY_APPROVALS: Symbol = symbol_short!("ER_APPRVS");
-const KEY_DEST: Symbol = symbol_short!("ER_DEST");
-const KEY_TOKEN: Symbol = symbol_short!("ER_TOKEN");
-const KEY_AMOUNT: Symbol = symbol_short!("ER_AMOUNT");
-const ZERO_ADDRESS: &str = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF";
+const KEY_DEST: Symbol = symbol_short!("ER_DEST");
+const KEY_TOKEN: Symbol = symbol_short!("ER_TOKEN");
+const KEY_AMOUNT: Symbol = symbol_short!("ER_AMOUNT");
+const ZERO_ADDRESS: &str = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF";
#[contracterror]
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
-
pub enum RecoveryError {
- NotAdmin = 1,
- AlreadyApproved = 2,
- ThresholdNotMet = 3,
- NoPendingRequest = 4,
- InvalidThreshold = 5,
- InvalidAddress = 6,
- InvalidAmount = 7,
-
- DuplicateAdmin = 8,
-
- AlreadyInitialized = 8,
-
+ NotAdmin = 1,
+ AlreadyApproved = 2,
+ ThresholdNotMet = 3,
+ NoPendingRequest = 4,
+ InvalidThreshold = 5,
+ InvalidAddress = 6,
+ InvalidAmount = 7,
+ DuplicateAdmin = 8,
+ AlreadyInitialized = 9,
}
pub fn init(env: &Env, admins: Vec, threshold: u32) {
-
- if threshold == 0 || threshold > admins.len() {
- panic_with_error!(env, RecoveryError::InvalidThreshold);
- }
- ensure_unique_admins(env, &admins);
- for admin in admins.iter() {
- validate_address(env, &admin);
- }
-
if env.storage().instance().has(&KEY_ADMINS) {
panic_with_error!(env, RecoveryError::AlreadyInitialized);
}
if threshold == 0 || threshold > admins.len() {
panic_with_error!(env, RecoveryError::InvalidThreshold);
}
-
let mut seen = Vec::new(env);
for admin in admins.iter() {
validate_address(env, &admin);
if seen.contains(&admin) {
- panic_with_error!(env, RecoveryError::InvalidThreshold);
+ panic_with_error!(env, RecoveryError::DuplicateAdmin);
}
seen.push_back(admin);
}
-
-
env.storage().instance().set(&KEY_ADMINS, &admins);
env.storage().instance().set(&KEY_THRESH, &threshold);
clear_pending(env);
@@ -102,17 +73,7 @@ pub fn request(env: &Env, requester: &Address, token: &Address, dest: &Address,
approvals.push_back(requester.clone());
env.storage().instance().set(&KEY_APPROVALS, &approvals);
- publish_event(
- env,
- MOD_RECOVERY | ACT_REQUEST,
-
- amount_as_u64(env, amount),
- BytesN::from_array(env, &[0u8; 32]),
-
- event_amount(env, amount),
- zero_hash(env),
-
- );
+ publish_event(env, MOD_RECOVERY | ACT_REQUEST, event_amount(env, amount), zero_hash(env));
let threshold: u32 = env.storage().instance().get(&KEY_THRESH).unwrap_or(1);
if approvals.len() >= threshold {
@@ -151,14 +112,6 @@ pub fn approve(env: &Env, admin: &Address) {
}
}
-
-pub fn approvals(env: &Env) -> Vec {
- env.storage().instance().get(&KEY_APPROVALS).unwrap_or(vec![env])
-}
-
-fn execute_recovery(env: &Env, dest: &Address) {
- assert_closed(env);
-
pub fn pending_approvals(env: &Env) -> Vec {
env.storage()
.instance()
@@ -167,6 +120,7 @@ pub fn pending_approvals(env: &Env) -> Vec {
}
fn execute_recovery(env: &Env, dest: &Address) {
+ assert_closed(env);
let token: Address = env
.storage()
@@ -180,17 +134,7 @@ fn execute_recovery(env: &Env, dest: &Address) {
.unwrap_or_else(|| panic_with_error!(env, RecoveryError::NoPendingRequest));
token::Client::new(env, &token).transfer(&env.current_contract_address(), dest, &amount);
- publish_event(
- env,
- MOD_RECOVERY | ACT_TRIGGERED,
-
- amount_as_u64(env, amount),
- BytesN::from_array(env, &[0u8; 32]),
-
- event_amount(env, amount),
- zero_hash(env),
-
- );
+ publish_event(env, MOD_RECOVERY | ACT_TRIGGERED, event_amount(env, amount), zero_hash(env));
clear_pending(env);
}
@@ -210,37 +154,14 @@ fn require_admin(env: &Env, caller: &Address) {
}
fn validate_address(env: &Env, addr: &Address) {
-
- if addr.to_string().is_empty() {
- panic_with_error!(env, RecoveryError::InvalidAddress);
- }
let zero = String::from_str(env, ZERO_ADDRESS);
if addr.to_string() == zero {
-
- let zero = String::from_str(env, ZERO_ADDRESS);
- if addr.to_string().is_empty() || addr.to_string() == zero {
-
panic_with_error!(env, RecoveryError::InvalidAddress);
}
}
-
-fn ensure_unique_admins(env: &Env, admins: &Vec) {
- let mut seen = vec![env];
- for admin in admins.iter() {
- if seen.contains(&admin) {
- panic_with_error!(env, RecoveryError::DuplicateAdmin);
- }
- seen.push_back(admin);
- }
-}
-
-fn amount_as_u64(env: &Env, amount: i128) -> u64 {
- if amount < 0 || amount > u64::MAX as i128 {
-
fn event_amount(env: &Env, amount: i128) -> u64 {
if amount <= 0 || amount > u64::MAX as i128 {
-
panic_with_error!(env, RecoveryError::InvalidAmount);
}
amount as u64
@@ -257,20 +178,12 @@ mod tests {
#[contractimpl]
impl TestContract {}
-
- fn setup(env: &Env, threshold: u32) -> (Address, Vec) {
- let contract_id = env.register_contract(None, TestContract);
- let a0 = Address::generate(env);
- let a1 = Address::generate(env);
- let admins = vec![env, a0, a1];
-
- fn setup(env: &Env, admin_count: u32, threshold: u32) -> (soroban_sdk::Address, Vec) {
+ fn setup(env: &Env, admin_count: u32, threshold: u32) -> (Address, Vec) {
let contract_id = env.register_contract(None, TestContract);
let mut admins = vec![env];
for _ in 0..admin_count {
admins.push_back(Address::generate(env));
}
-
env.as_contract(&contract_id, || init(env, admins.clone(), threshold));
(contract_id, admins)
}
@@ -279,11 +192,6 @@ mod tests {
#[should_panic]
fn init_rejects_zero_threshold() {
let env = Env::default();
-
- let contract_id = env.register_contract(None, TestContract);
- let a = Address::generate(&env);
- env.as_contract(&contract_id, || init(&env, vec![&env, a], 0));
-
let a = Address::generate(&env);
let contract_id = env.register_contract(None, TestContract);
env.as_contract(&contract_id, || init(&env, vec![&env, a], 0));
@@ -296,7 +204,6 @@ mod tests {
let a = Address::generate(&env);
let contract_id = env.register_contract(None, TestContract);
env.as_contract(&contract_id, || init(&env, vec![&env, a], 2));
-
}
#[test]
@@ -304,13 +211,6 @@ mod tests {
fn non_admin_cannot_request() {
let env = Env::default();
env.mock_all_auths();
-
- let (contract_id, _) = setup(&env, 2);
- let rogue = Address::generate(&env);
- let token = Address::generate(&env);
- let dest = Address::generate(&env);
- env.as_contract(&contract_id, || request(&env, &rogue, &token, &dest, 1000));
-
let (contract_id, _) = setup(&env, 2, 2);
let rogue = Address::generate(&env);
let token = Address::generate(&env);
@@ -331,27 +231,19 @@ mod tests {
request(&env, &admin, &token, &dest, 1000);
approve(&env, &admin);
});
-
}
#[test]
fn single_approval_does_not_execute_when_threshold_is_two() {
let env = Env::default();
env.mock_all_auths();
- let (contract_id, admins) = setup(&env, 2);
+ let (contract_id, admins) = setup(&env, 2, 2);
let token = Address::generate(&env);
let dest = Address::generate(&env);
-
- let a0 = admins.get(0).unwrap();
- env.as_contract(&contract_id, || {
- request(&env, &a0, &token, &dest, 500);
- assert_eq!(approvals(&env).len(), 1);
-
let admin = admins.get(0).unwrap();
env.as_contract(&contract_id, || {
request(&env, &admin, &token, &dest, 500);
assert_eq!(pending_approvals(&env).len(), 1);
-
});
}
}
diff --git a/engine-core/src/event_struct.rs b/engine-core/src/event_struct.rs
index 0267a33..23b7e35 100644
--- a/engine-core/src/event_struct.rs
+++ b/engine-core/src/event_struct.rs
@@ -1,102 +1,50 @@
-
-//! Compact event encoding for audit-friendly Soroban logs.
-//!
-//! `CompactEvent` replaces heap-heavy, loosely typed event payloads with a flat
-//! structure that is deterministic, cheap to emit, and easy for indexers to
-//! verify. The `flags` field packs a module id and action id into one `u32`.
-
//! Compact event encoding for audit-ready Soroban logs.
-
//!
-//! `CompactEvent` keeps on-chain events small and deterministic while still
-//! giving the relayer/dashboard enough data to reconstruct the control-plane
-//! audit trail. `flags` packs a module id and an action id; `value` carries the
-//! primary numeric datum; `hash` carries a state/action hash when present.
-
-use soroban_sdk::{contracttype, BytesN};
-
-
-// Compact event encoding — bitmask-based event struct.
-//
-// Replaces the previous fat `Event { event_type: BytesN<32>, action: BytesN<32>, payload: Map }`
-// which wasted 64 bytes of zeroed data and allocated an expensive `Map` on every call.
-//
-// ## Encoding
-//
-// `flags` packs module id (bits 0–7) and action id (bits 8–15) into a single `u32`:
-//
-// ```text
-// bits 0– 7 : module id (MOD_*)
-// bits 8–15 : action id (ACT_*)
-// bits 16–31 : reserved for future use / version
-// ```
-//
-// `value` carries a u64 primary value (sequence, proposal id, amount, …).
-// `hash` carries an optional 32-byte hash (state_hash, action_hash). Zero if unused.
-
+//! `flags` packs module id (bits 0–7) and action id (bits 8–15) into a `u32`:
+//!
+//! ```text
+//! bits 0– 7 : module id (MOD_*)
+//! bits 8–15 : action id (ACT_*)
+//! bits 16–31 : reserved
+//! ```
+//!
+//! `value` carries a u64 primary value (sequence, proposal id, amount, …).
+//! `hash` carries an optional 32-byte hash. All-zero when unused.
use soroban_sdk::{contracttype, BytesN};
+// ── module ids ────────────────────────────────────────────────────────────────
-// Module ids (bits 0..=7).
-
-pub const MOD_AUDIT: u32 = 0x01;
-pub const MOD_GOV: u32 = 0x02;
+pub const MOD_AUDIT: u32 = 0x01;
+pub const MOD_GOV: u32 = 0x02;
pub const MOD_TREASURY: u32 = 0x03;
-pub const MOD_CB: u32 = 0x04;
-pub const MOD_BURN: u32 = 0x05;
+pub const MOD_CB: u32 = 0x04;
+pub const MOD_BURN: u32 = 0x05;
pub const MOD_RECOVERY: u32 = 0x06;
pub const MOD_FEE: u32 = 0x07;
-pub const MOD_CORE: u32 = 0x08;
-pub const MOD_FEE: u32 = 0x07;
-
-
-// Action ids (bits 8..=15).
-
-pub const MOD_UPGRADE: u32 = 0x08;
+pub const MOD_UPGRADE: u32 = 0x08;
// ── action ids ────────────────────────────────────────────────────────────────
-
-pub const ACT_COMMIT: u32 = 0x01 << 8;
-pub const ACT_SNAPSHOT: u32 = 0x02 << 8;
-pub const ACT_PROPOSE: u32 = 0x03 << 8;
-pub const ACT_APPROVE: u32 = 0x04 << 8;
-pub const ACT_EXECUTE: u32 = 0x05 << 8;
-pub const ACT_TRIP: u32 = 0x06 << 8;
-pub const ACT_RESET: u32 = 0x07 << 8;
-pub const ACT_BURN_SAFE: u32 = 0x08 << 8;
-pub const ACT_REQUEST: u32 = 0x09 << 8;
-
-pub const ACT_TRIGGERED: u32 = 0x0a << 8;
-pub const ACT_FEE: u32 = 0x0b << 8;
-
-#[contracttype]
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct CompactEvent {
- pub flags: u32,
- pub value: u64,
-
-pub const ACT_TRIGGERED: u32 = 0x0A << 8;
-pub const ACT_FEE: u32 = 0x0B << 8;
-pub const ACT_INIT: u32 = 0x0C << 8;
-pub const ACT_TRANSITION: u32 = 0x0D << 8;
-pub const ACT_FEE: u32 = 0x0B << 8;
-pub const ACT_UPGRADE: u32 = 0x0C << 8;
-pub const ACT_UPDATE: u32 = 0x0D << 8;
-
-/// Compact event struct emitted by all engine-core modules.
+pub const ACT_COMMIT: u32 = 0x01 << 8;
+pub const ACT_SNAPSHOT: u32 = 0x02 << 8;
+pub const ACT_PROPOSE: u32 = 0x03 << 8;
+pub const ACT_APPROVE: u32 = 0x04 << 8;
+pub const ACT_EXECUTE: u32 = 0x05 << 8;
+pub const ACT_TRIP: u32 = 0x06 << 8;
+pub const ACT_RESET: u32 = 0x07 << 8;
+pub const ACT_BURN_SAFE: u32 = 0x08 << 8;
+pub const ACT_REQUEST: u32 = 0x09 << 8;
+pub const ACT_TRIGGERED: u32 = 0x0A << 8;
+pub const ACT_FEE: u32 = 0x0B << 8;
+pub const ACT_FEE_TRANSFER: u32 = 0x0C << 8;
+pub const ACT_UPGRADE: u32 = 0x0D << 8;
+
+/// Compact event struct — flat, zero heap allocation.
#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct CompactEvent {
- /// Packed module + action bitmask. Use `MOD_* | ACT_*` constants.
pub flags: u32,
- /// Primary numeric value — sequence number, proposal id, amount, etc.
pub value: u64,
-
- /// Optional 32-byte hash (state_hash, action_hash). All-zero when unused.
-
- /// Optional 32-byte hash (all-zero when unused).
-
- pub hash: BytesN<32>,
+ pub hash: BytesN<32>,
}
diff --git a/engine-core/src/event_utils.rs b/engine-core/src/event_utils.rs
index d866fe6..1d75846 100644
--- a/engine-core/src/event_utils.rs
+++ b/engine-core/src/event_utils.rs
@@ -1,43 +1,16 @@
+//! Event publishing helpers — emit a `CompactEvent` via the Soroban event log.
-use soroban_sdk::{symbol_short, BytesN, Env, Map, Symbol, Val};
-
-//! Event publishing helpers.
-
-
-use crate::event_struct::CompactEvent;
use soroban_sdk::{symbol_short, BytesN, Env};
+use crate::event_struct::CompactEvent;
-/// Publish a deterministic compact event under a single topic for indexing.
-pub fn publish_event(env: &Env, flags: u32, value: u64, hash: BytesN<32>) {
- let ev = CompactEvent { flags, value, hash };
- env.events()
- .publish((symbol_short!("EVENT"), symbol_short!("LOG")), ev);
-
-/// Publish a compact, structured event.
-///
-/// `flags` is built by OR-ing a `MOD_*` constant with an `ACT_*` constant from
-/// [`crate::event_struct`]. The event topic is intentionally stable so the
-/// off-chain bridge can consume every engine-core event with one subscription.
pub fn publish_event(env: &Env, flags: u32, value: u64, hash: BytesN<32>) {
-
let ev = CompactEvent { flags, value, hash };
env.events()
.publish((symbol_short!("EVENT"), symbol_short!("LOG")), ev);
-
- let event = CompactEvent { flags, value, hash };
- env.events()
- .publish((symbol_short!("EVENT"), symbol_short!("LOG")), event);
}
-/// Return the canonical all-zero hash used when an event has no hash payload.
+/// Canonical all-zero 32-byte hash for events that carry no hash payload.
pub fn zero_hash(env: &Env) -> BytesN<32> {
BytesN::from_array(env, &[0u8; 32])
-
-}
-
-/// Compatibility function for legacy events.
-pub fn publish_event_legacy(env: &Env, event_type: BytesN<32>, action: BytesN<32>, payload: Map) {
- // legacy publish
- env.events().publish((event_type, action), payload);
}
diff --git a/engine-core/src/governance.rs b/engine-core/src/governance.rs
index 25e3e57..324e1a1 100644
--- a/engine-core/src/governance.rs
+++ b/engine-core/src/governance.rs
@@ -1,156 +1,53 @@
-
-//! Multi-signature governance with timelock.
-//!
-//! Proposals are stored individually in persistent storage to keep the instance
-//! footprint bounded. A proposal moves through exactly this state machine:
-//!
-//! `Pending -> Approved -> Executed`.
-
-use crate::circuit_breaker::assert_closed;
-use crate::event_struct::{ACT_APPROVE, ACT_EXECUTE, ACT_PROPOSE, MOD_GOV};
-use crate::event_utils::publish_event;
-use crate::types::{Proposal, ProposalState};
-use soroban_sdk::{contracterror, contracttype, panic_with_error, symbol_short, vec, Address, BytesN, Env, Symbol, Vec};
-
-const KEY_SIGNERS: Symbol = symbol_short!("SIGNERS");
-const KEY_THRESH: Symbol = symbol_short!("THRESH");
-
-/// Ledgers to wait after quorum before execution (~1 hour on Stellar).
-pub const TIMELOCK_LEDGERS: u32 = 720;
-const PROPOSAL_TTL_THRESHOLD: u32 = 17_280;
-const PROPOSAL_TTL_EXTEND_TO: u32 = 17_280 * 30;
-
-#[contracttype]
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub enum GovKey {
- Proposal(u64),
-}
-
-//! Multi-sig governance with explicit proposal-state transitions and timelock.
+//! Multi-sig governance with timelock.
//!
-
-//! ## Proposal State Machine
-
-//! State machine:
-//!
-
-//! ```text
-//! Pending ──(threshold approvals)──> Approved ──(timelock elapsed)──> Executed
-//! ```
+//! `Pending → Approved → Executed`
//!
-//! Invalid transitions panic with typed `GovError` values for auditability.
+//! Invalid transitions panic with typed `GovError` values.
-
-use crate::event_struct::{ACT_APPROVE, ACT_EXECUTE, ACT_PROPOSE, MOD_GOV};
-use crate::event_utils::publish_event;
-use crate::types::{Proposal, ProposalState};
use soroban_sdk::{
- contracterror, panic_with_error, symbol_short, vec, Address, Env, Map, Symbol, Vec,
+ contracterror, panic_with_error, symbol_short, token, vec, Address, BytesN, Env, Map, Symbol, Vec,
};
-const KEY_PROPOSALS: Symbol = symbol_short!("PROPS");
-const KEY_SIGNERS: Symbol = symbol_short!("SIGNERS");
-const KEY_THRESH: Symbol = symbol_short!("THRESH");
-
-/// Ledgers to wait after full approval before execution (~1 hour on Stellar).
-const TIMELOCK_LEDGERS: u32 = 720;
-
use crate::circuit_breaker::assert_closed;
use crate::event_struct::{ACT_APPROVE, ACT_EXECUTE, ACT_PROPOSE, MOD_GOV};
use crate::event_utils::{publish_event, zero_hash};
use crate::types::{Proposal, ProposalState};
-use soroban_sdk::{
-
- contracterror, panic_with_error, symbol_short, vec, Address, BytesN, Env, Map, Symbol, Vec,
-
- contracterror, panic_with_error, symbol_short, token, vec, Address, Env, Map, Symbol, Vec, BytesN,
-
-};
const KEY_PROPOSALS: Symbol = symbol_short!("PROPS");
-const KEY_SIGNERS: Symbol = symbol_short!("SIGNERS");
-const KEY_THRESH: Symbol = symbol_short!("THRESH");
-
-
-/// Ledgers to wait after full approval before execution (~1 hour on Stellar).
-const TIMELOCK_LEDGERS: u32 = 720;
-
-#[contracterror]
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-
+const KEY_SIGNERS: Symbol = symbol_short!("SIGNERS");
+const KEY_THRESH: Symbol = symbol_short!("THRESH");
const KEY_MIN_STAKE: Symbol = symbol_short!("MINSTAKE");
const KEY_STAKE_TOK: Symbol = symbol_short!("STKTOK");
-/// Ledgers to wait after threshold approval before execution (~1 hour).
+/// Ledgers to wait after quorum before execution (~1 hour on Stellar).
pub const TIMELOCK_LEDGERS: u32 = 720;
const MAX_THRESHOLD: u32 = 100;
-
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
-
pub enum GovError {
- NotASigner = 1,
- AlreadyApproved = 2,
- ProposalNotFound = 3,
- TimelockActive = 4,
+ NotASigner = 1,
+ AlreadyApproved = 2,
+ ThresholdNotMet = 3,
+ TimelockActive = 4,
InvalidStateTransition = 5,
-
- InvalidThreshold = 6,
-
- ProposalNotFound = 6,
- InvalidThreshold = 7,
-
- DuplicateSigner = 8,
- DuplicateProposal = 9,
-}
-
-/// Initialise governance with a signer set and approval threshold.
-pub fn init(env: &Env, signers: Vec, threshold: u32) {
- if threshold == 0 || threshold > signers.len() {
- panic_with_error!(env, GovError::InvalidThreshold);
- }
- ensure_unique_signers(env, &signers);
- env.storage().instance().set(&KEY_SIGNERS, &signers);
- env.storage().instance().set(&KEY_THRESH, &threshold);
-}
-
-/// Return configured signers.
-pub fn signers(env: &Env) -> Vec {
- env.storage().instance().get(&KEY_SIGNERS).unwrap_or(vec![env])
-}
-
-/// Return configured approval threshold.
-pub fn threshold(env: &Env) -> u32 {
- env.storage().instance().get(&KEY_THRESH).unwrap_or(1)
-}
-
-/// Submit a new proposal. Returns the proposal id.
-pub fn propose(env: &Env, proposal: Proposal) -> u64 {
- crate::non_reentrant!(env);
- assert_closed(env);
- let signers = signers(env);
-
- InvalidStake = 8,
- AlreadyInitialized = 9,
- ProposalAlreadyExists = 10,
- InvalidProposal = 11,
- ArithmeticOverflow = 12,
+ ProposalNotFound = 6,
+ InvalidThreshold = 7,
+ InvalidStake = 8,
+ AlreadyInitialized = 9,
+ ProposalAlreadyExists = 10,
+ ArithmeticOverflow = 11,
}
+/// Initialise governance with `signers` and a minimum-approval `threshold`.
pub fn init(env: &Env, signers: Vec, threshold: u32) {
-
- if threshold == 0 || threshold > signers.len() {
- panic_with_error!(env, GovError::InvalidThreshold);
- }
-
init_internal(env, signers, threshold, None, 0);
}
/// Initialise governance with an optional anti-Sybil stake gate.
///
-/// `min_stake == 0` disables the stake gate. When enabled, every approving
-/// signer must hold at least `min_stake` units of `stake_token`.
+/// Set `min_stake = 0` to disable the gate. When enabled every approver must
+/// hold at least `min_stake` units of `stake_token`.
pub fn init_with_stake(
env: &Env,
signers: Vec,
@@ -169,40 +66,33 @@ fn init_internal(
min_stake: i128,
) {
crate::non_reentrant!(env);
-
if env.storage().instance().has(&KEY_SIGNERS) {
panic_with_error!(env, GovError::AlreadyInitialized);
}
- if threshold == 0 || threshold > signers.len() || threshold > MAX_THRESHOLD {
+ if threshold == 0 || threshold > signers.len() as u32 || threshold > MAX_THRESHOLD {
panic_with_error!(env, GovError::InvalidThreshold);
}
if min_stake < 0 || (min_stake > 0 && stake_token.is_none()) {
panic_with_error!(env, GovError::InvalidStake);
}
-
let mut seen = Vec::new(env);
- for signer in signers.iter() {
- if seen.contains(&signer) {
+ for s in signers.iter() {
+ if seen.contains(&s) {
panic_with_error!(env, GovError::InvalidThreshold);
}
- seen.push_back(signer);
+ seen.push_back(s);
}
-
-
env.storage().instance().set(&KEY_SIGNERS, &signers);
env.storage().instance().set(&KEY_THRESH, &threshold);
env.storage().instance().set(&KEY_MIN_STAKE, &min_stake);
- if let Some(token) = stake_token {
- env.storage().instance().set(&KEY_STAKE_TOK, &token);
+ if let Some(tok) = stake_token {
+ env.storage().instance().set(&KEY_STAKE_TOK, &tok);
}
-
let empty: Map = Map::new(env);
env.storage().instance().set(&KEY_PROPOSALS, &empty);
}
-
-/// Load the proposal map. Public for tests and read-only off-chain simulation.
-
+/// All proposals keyed by proposal id, value is `(Proposal, unlock_ledger)`.
pub fn load_proposals(env: &Env) -> Map {
env.storage()
.instance()
@@ -210,12 +100,8 @@ pub fn load_proposals(env: &Env) -> Map {
.unwrap_or(Map::new(env))
}
-
-/// Submit a new proposal. Returns the assigned proposal id.
-pub fn propose(env: &Env, proposal: Proposal) -> u64 {
-
-fn save_proposals(env: &Env, proposals: &Map) {
- env.storage().instance().set(&KEY_PROPOSALS, proposals);
+fn save_proposals(env: &Env, m: &Map) {
+ env.storage().instance().set(&KEY_PROPOSALS, m);
}
fn load_signers(env: &Env) -> Vec {
@@ -230,231 +116,92 @@ fn threshold(env: &Env) -> u32 {
}
fn require_signer(env: &Env, signer: &Address) {
- let signers = load_signers(env);
- if !signers.contains(signer) {
+ if !load_signers(env).contains(signer) {
panic_with_error!(env, GovError::NotASigner);
}
}
-fn signer_index(env: &Env, signer: &Address) -> u32 {
- let signers = load_signers(env);
-
- for i in 0..signers.len() {
- if signers.get(i).unwrap() == *signer {
- return i;
- }
- }
-
- panic_with_error!(env, GovError::NotASigner);
-}
-
fn require_stake(env: &Env, signer: &Address) {
- let min_stake: i128 = env.storage().instance().get(&KEY_MIN_STAKE).unwrap_or(0);
- if min_stake == 0 {
+ let min: i128 = env.storage().instance().get(&KEY_MIN_STAKE).unwrap_or(0);
+ if min == 0 {
return;
}
- let stake_token: Address = env
+ let tok: Address = env
.storage()
.instance()
.get(&KEY_STAKE_TOK)
.unwrap_or_else(|| panic_with_error!(env, GovError::InvalidStake));
- let balance = token::Client::new(env, &stake_token).balance(signer);
- if balance < min_stake {
+ if token::Client::new(env, &tok).balance(signer) < min {
panic_with_error!(env, GovError::InvalidStake);
}
}
+/// Submit a new proposal. `proposal.proposer` must be an authorised signer.
+pub fn propose(env: &Env, proposal: Proposal) -> u64 {
+ crate::non_reentrant!(env);
+ require_signer(env, &proposal.proposer);
-pub fn propose(env: &Env, mut proposal: Proposal) -> u64 {
-
- let signers: Vec = env
- .storage()
- .instance()
- .get(&KEY_SIGNERS)
- .unwrap_or(vec![env]);
-
- if !signers.contains(&proposal.proposer) {
- panic_with_error!(env, GovError::NotASigner);
- }
-
-
-
- proposal.proposer.require_auth();
-
-
- let key = proposal_key(proposal.id);
- if env.storage().persistent().has(&key) {
- panic_with_error!(env, GovError::DuplicateProposal);
+ let id = proposal.id;
+ let mut props = load_proposals(env);
+ if props.contains_key(id) {
+ panic_with_error!(env, GovError::ProposalAlreadyExists);
}
- let id = proposal.id;
let mut prop = proposal;
prop.state = ProposalState::Pending;
- prop.approved_by = vec![env];
- let unlock_ledger = env.ledger().sequence() + TIMELOCK_LEDGERS;
+ props.set(id, (prop, 0u32));
+ save_proposals(env, &props);
- env.storage().persistent().set(&key, &(prop, unlock_ledger));
- extend_proposal_ttl(env, &key);
-
- publish_event(env, MOD_GOV | ACT_PROPOSE, id, BytesN::from_array(env, &[0u8; 32]));
+ publish_event(env, MOD_GOV | ACT_PROPOSE, id, zero_hash(env));
id
}
-/// Record one signer approval. When quorum is reached, state becomes Approved.
-
-
- // Initialize state to Pending
-
- proposal.state = ProposalState::Pending;
-
- let mut props = load_proposals(env);
- let unlock_ledger = env.ledger().sequence() + TIMELOCK_LEDGERS;
-
- props.set(proposal.id, (proposal.clone(), unlock_ledger));
- env.storage().instance().set(&KEY_PROPOSALS, &props);
-
- // Single compact event.
-
- let id = proposal.id;
- props.set(id, (proposal.clone(), unlock_ledger));
- env.storage().instance().set(&KEY_PROPOSALS, &props);
-
-
- publish_event(
- env,
- MOD_GOV | ACT_PROPOSE,
- proposal.id,
-
- proposal.action_hash.clone(),
- );
-
-
- BytesN::from_array(env, &[0u8; 32]),
- );
-
- proposal.id
-}
-
-
+/// Record `signer`'s approval. Transitions `Pending → Approved` at threshold.
pub fn approve(env: &Env, signer: &Address, proposal_id: u64) {
- crate::circuit_breaker::assert_closed(env);
- crate::non_reentrant!(env);
+ let _guard = crate::guards::ReentrancyGuard::enter(env);
assert_closed(env);
-
- signer.require_auth();
- let configured = signers(env);
- if !configured.contains(signer) {
- panic_with_error!(env, GovError::NotASigner);
- }
-
- let key = proposal_key(proposal_id);
- let (mut prop, unlock): (Proposal, u32) = env
- .storage()
- .persistent()
- .get(&key)
- .unwrap_or_else(|| panic_with_error!(env, GovError::ProposalNotFound));
-
- if prop.state != ProposalState::Pending {
- panic_with_error!(env, GovError::InvalidStateTransition);
- }
- if prop.approved_by.contains(signer) {
- panic_with_error!(env, GovError::AlreadyApproved);
- }
-
- prop.approved_by.push_back(signer.clone());
- if prop.approved_by.len() >= threshold(env) {
- prop.state = ProposalState::Approved;
-
-
signer.require_auth();
require_signer(env, signer);
require_stake(env, signer);
+ let thresh = threshold(env);
+ if thresh == 0 {
+ panic_with_error!(env, GovError::InvalidThreshold);
+ }
- let mut proposals = load_proposals(env);
- let (mut proposal, mut unlock_ledger) = proposals
+ let mut props = load_proposals(env);
+ let (mut prop, mut unlock) = props
.get(proposal_id)
.unwrap_or_else(|| panic_with_error!(env, GovError::ProposalNotFound));
-
if prop.state != ProposalState::Pending {
-
- if proposal.state != ProposalState::Pending {
-
panic_with_error!(env, GovError::InvalidStateTransition);
}
- if proposal.approved_by.contains(signer) {
- panic_with_error!(env, GovError::AlreadyApproved);
-}
-
-if proposal.approved_by.len() > 0 {
- let last_signer = proposal
- .approved_by
- .get(proposal.approved_by.len() - 1)
- .unwrap();
-
- let last_index = signer_index(env, &last_signer);
- let current_index = signer_index(env, signer);
-
- if current_index <= last_index {
- panic_with_error!(env, GovError::InvalidSignerOrder);
+ if prop.approved_by.contains(signer) {
+ panic_with_error!(env, GovError::AlreadyApproved);
}
-}
-
-proposal.approved_by.push_back(signer.clone());
- proposal.approved_by.push_back(signer.clone());
+ prop.approved_by.push_back(signer.clone());
- if (prop.approved_by.len() as u32) >= threshold {
+ if prop.approved_by.len() as u32 >= thresh {
prop.state = ProposalState::Approved;
- }
-
- props.set(proposal_id, (prop.clone(), unlock));
- env.storage().instance().set(&KEY_PROPOSALS, &props);
-
- if prop.state == ProposalState::Approved {
- publish_event(
- env,
- MOD_GOV | ACT_APPROVE,
- proposal_id,
- BytesN::from_array(env, &[0u8; 32]),
- );
- }
-
- let approval_threshold = threshold(env);
- if approval_threshold == 0 {
- panic_with_error!(env, GovError::InvalidThreshold);
- }
-
- if proposal.approved_by.len() >= approval_threshold {
- proposal.state = ProposalState::Approved;
- unlock_ledger = env
+ unlock = env
.ledger()
.sequence()
.checked_add(TIMELOCK_LEDGERS)
.unwrap_or_else(|| panic_with_error!(env, GovError::ArithmeticOverflow));
-
}
- proposals.set(proposal_id, (proposal, unlock_ledger));
- save_proposals(env, &proposals);
-
-
- publish_event(env, MOD_GOV | ACT_APPROVE, proposal_id, prop.action_hash.clone());
-}
-
-/// Execute an approved proposal after the timelock expires.
+ props.set(proposal_id, (prop, unlock));
+ save_proposals(env, &props);
publish_event(env, MOD_GOV | ACT_APPROVE, proposal_id, zero_hash(env));
-
}
-/// Execute an approved proposal after its timelock has elapsed.
-
+/// Execute an approved proposal after the timelock has elapsed.
pub fn execute(env: &Env, proposal_id: u64) -> Proposal {
- crate::circuit_breaker::assert_closed(env);
- crate::non_reentrant!(env);
-
+ let _guard = crate::guards::ReentrancyGuard::enter(env);
+ assert_closed(env);
let mut props = load_proposals(env);
let (mut prop, unlock) = props
@@ -470,112 +217,23 @@ pub fn execute(env: &Env, proposal_id: u64) -> Proposal {
prop.state = ProposalState::Executed;
props.set(proposal_id, (prop.clone(), unlock));
- env.storage().instance().set(&KEY_PROPOSALS, &props);
-
- assert_closed(env);
-
- let key = proposal_key(proposal_id);
- let (mut prop, unlock): (Proposal, u32) = env
- .storage()
- .persistent()
- .get(&key)
- .unwrap_or_else(|| panic_with_error!(env, GovError::ProposalNotFound));
-
- if prop.state != ProposalState::Approved {
- panic_with_error!(env, GovError::InvalidStateTransition);
- }
- if env.ledger().sequence() < unlock {
- panic_with_error!(env, GovError::TimelockActive);
- }
-
- prop.state = ProposalState::Executed;
- env.storage().persistent().set(&key, &(prop.clone(), unlock));
- extend_proposal_ttl(env, &key);
+ save_proposals(env, &props);
publish_event(env, MOD_GOV | ACT_EXECUTE, proposal_id, prop.action_hash.clone());
prop
}
-pub fn get_proposal(env: &Env, proposal_id: u64) -> Proposal {
- let key = proposal_key(proposal_id);
- let (prop, _): (Proposal, u32) = env
- .storage()
- .persistent()
- .get(&key)
- .unwrap_or_else(|| panic_with_error!(env, GovError::ProposalNotFound));
- prop
-}
-
-pub fn get_proposal_with_unlock(env: &Env, proposal_id: u64) -> (Proposal, u32) {
- let key = proposal_key(proposal_id);
- env.storage()
- .persistent()
- .get(&key)
- .unwrap_or_else(|| panic_with_error!(env, GovError::ProposalNotFound))
-}
-
-fn proposal_key(id: u64) -> GovKey {
- GovKey::Proposal(id)
-}
-
-fn extend_proposal_ttl(env: &Env, key: &GovKey) {
- env.storage()
- .persistent()
- .extend_ttl(key, PROPOSAL_TTL_THRESHOLD, PROPOSAL_TTL_EXTEND_TO);
-}
-
-fn ensure_unique_signers(env: &Env, signers: &Vec) {
- let mut seen = vec![env];
- for signer in signers.iter() {
- if seen.contains(&signer) {
- panic_with_error!(env, GovError::DuplicateSigner);
- }
- seen.push_back(signer);
-
-
- let mut proposals = load_proposals(env);
- let (mut proposal, unlock_ledger) = proposals
- .get(proposal_id)
- .unwrap_or_else(|| panic_with_error!(env, GovError::ProposalNotFound));
-
- if proposal.state != ProposalState::Approved {
- panic_with_error!(env, GovError::InvalidStateTransition);
- }
- if proposal.approved_by.len() < threshold(env) {
- panic_with_error!(env, GovError::ThresholdNotMet);
- }
- if env.ledger().sequence() < unlock_ledger {
- panic_with_error!(env, GovError::TimelockActive);
- }
-
- proposal.state = ProposalState::Executed;
- proposals.set(proposal_id, (proposal.clone(), unlock_ledger));
- save_proposals(env, &proposals);
-
-
- publish_event(
- env,
- MOD_GOV | ACT_EXECUTE,
- proposal_id,
- proposal.action_hash.clone(),
- );
- proposal
-}
-
-
/// Return a proposal or panic with `ProposalNotFound`.
pub fn get_proposal(env: &Env, proposal_id: u64) -> Proposal {
- let (proposal, _) = load_proposals(env)
+ let (prop, _) = load_proposals(env)
.get(proposal_id)
.unwrap_or_else(|| panic_with_error!(env, GovError::ProposalNotFound));
- proposal
+ prop
}
-/// Return a proposal's unlock ledger, if it exists.
+/// Return a proposal's unlock ledger, or `None` if not found.
pub fn get_unlock_ledger(env: &Env, proposal_id: u64) -> Option {
- load_proposals(env)
- .get(proposal_id)
- .map(|(_, unlock)| unlock)
+ load_proposals(env).get(proposal_id).map(|(_, unlock)| unlock)
}
#[cfg(test)]
@@ -595,7 +253,7 @@ mod tests {
action_hash: BytesN::from_array(env, &[7u8; 32]),
proposer,
approved_by: vec![env],
- state: ProposalState::Executed,
+ state: ProposalState::Pending,
}
}
@@ -609,20 +267,12 @@ mod tests {
env.as_contract(&contract_id, || {
init(&env, vec![&env, alice.clone(), bob.clone()], 2);
- });
- env.as_contract(&contract_id, || {
- propose(&env, proposal(&env, 1, alice.clone()));
- });
- env.as_contract(&contract_id, || {
+ let _ = propose(&env, proposal(&env, 1, alice.clone()));
approve(&env, &alice, 1);
assert_eq!(get_proposal(&env, 1).state, ProposalState::Pending);
- });
- env.as_contract(&contract_id, || {
approve(&env, &bob, 1);
assert_eq!(get_proposal(&env, 1).state, ProposalState::Approved);
assert_eq!(get_unlock_ledger(&env, 1), Some(TIMELOCK_LEDGERS));
});
-
}
}
-
diff --git a/engine-core/src/governance_tests.rs b/engine-core/src/governance_tests.rs
index b7587aa..1067dde 100644
--- a/engine-core/src/governance_tests.rs
+++ b/engine-core/src/governance_tests.rs
@@ -1,33 +1,29 @@
#[cfg(test)]
mod tests {
-
- use crate::governance::{GovError, self};
-
use crate::governance::{self, GovError};
-
use crate::types::{Proposal, ProposalState};
-
- use soroban_sdk::{contract, contractimpl, testutils::Address as _, testutils::Ledger as _, vec, Address, BytesN, Env};
-
use soroban_sdk::{
testutils::{Address as _, Ledger as _},
vec, Address, BytesN, Env,
};
-
#[soroban_sdk::contract]
pub struct TestContract;
#[soroban_sdk::contractimpl]
impl TestContract {}
- fn proposal(env: &Env, id: u64, proposer: Address) -> Proposal {
+ fn setup_env(env: &Env) -> Address {
+ env.register_contract(None, TestContract)
+ }
+
+ fn create_dummy_proposal(env: &Env, proposer: &Address) -> Proposal {
Proposal {
- id,
- action_hash: BytesN::from_array(env, &[7u8; 32]),
- proposer,
+ id: 1,
+ action_hash: BytesN::from_array(env, &[0u8; 32]),
+ proposer: proposer.clone(),
approved_by: vec![env],
- state: ProposalState::Executed,
+ state: ProposalState::Pending,
}
}
@@ -45,53 +41,27 @@ mod tests {
}
#[test]
- fn proposal_initial_state_is_pending() {
+ fn test_proposal_initial_state_pending() {
let env = Env::default();
env.mock_all_auths();
-
- let contract_id = env.register_contract(None, TestContract);
-
let contract_id = setup_env(&env);
-
let proposer = Address::generate(&env);
- env.mock_all_auths();
-
-
- env.mock_all_auths();
init_one_of_one(&env, &contract_id, &proposer);
let id = propose_default(&env, &contract_id, &proposer);
env.as_contract(&contract_id, || {
-
- governance::init(&env, vec![&env, proposer.clone()], 1);
- let id = governance::propose(&env, proposal(&env, 1, proposer));
- assert_eq!(governance::get_proposal(&env, id).state, ProposalState::Pending);
-
let (p, _) = governance::load_proposals(&env).get(id).unwrap();
assert_eq!(p.state, ProposalState::Pending);
-
});
}
#[test]
- fn pending_moves_to_approved_at_threshold() {
+ fn test_state_transition_pending_to_approved() {
let env = Env::default();
env.mock_all_auths();
-
- let contract_id = env.register_contract(None, TestContract);
-
let contract_id = setup_env(&env);
-
let proposer = Address::generate(&env);
- let approver = Address::generate(&env);
-
-
- env.as_contract(&contract_id, || {
- governance::init(&env, vec![&env, proposer.clone()], 1);
- let id = governance::propose(&env, proposal(&env, 1, proposer.clone()));
- governance::approve(&env, &proposer, id);
- assert_eq!(governance::get_proposal(&env, id).state, ProposalState::Approved);
init_one_of_one(&env, &contract_id, &proposer);
let id = propose_default(&env, &contract_id, &proposer);
@@ -99,88 +69,41 @@ mod tests {
env.as_contract(&contract_id, || {
let (p, unlock) = governance::load_proposals(&env).get(id).unwrap();
-
assert_eq!(p.state, ProposalState::Approved);
assert_eq!(unlock, governance::TIMELOCK_LEDGERS);
-
});
}
#[test]
- fn approved_moves_to_executed_after_timelock() {
+ fn test_state_transition_approved_to_executed() {
let env = Env::default();
env.mock_all_auths();
-
- let contract_id = env.register_contract(None, TestContract);
-
let contract_id = setup_env(&env);
-
let proposer = Address::generate(&env);
- let approver = Address::generate(&env);
-
-
- env.as_contract(&contract_id, || {
- governance::init(&env, vec![&env, proposer.clone()], 1);
- let id = governance::propose(&env, proposal(&env, 1, proposer.clone()));
- governance::approve(&env, &proposer, id);
- env.ledger().set_sequence_number(governance::TIMELOCK_LEDGERS + 1);
- let executed = governance::execute(&env, id);
- assert_eq!(executed.state, ProposalState::Executed);
init_one_of_one(&env, &contract_id, &proposer);
let id = propose_default(&env, &contract_id, &proposer);
env.as_contract(&contract_id, || governance::approve(&env, &proposer, id));
env.as_contract(&contract_id, || {
- env.ledger()
- .set_sequence_number(governance::TIMELOCK_LEDGERS + 1);
-
+ env.ledger().set_sequence_number(governance::TIMELOCK_LEDGERS + 1);
governance::execute(&env, id);
let (p, _) = governance::load_proposals(&env).get(id).unwrap();
assert_eq!(p.state, ProposalState::Executed);
-
});
}
#[test]
#[should_panic]
- fn double_approval_is_rejected() {
+ fn test_reject_approval_on_approved_proposal() {
let env = Env::default();
env.mock_all_auths();
-
- let contract_id = env.register_contract(None, TestContract);
- let proposer = Address::generate(&env);
- let other = Address::generate(&env);
-
- env.as_contract(&contract_id, || {
- governance::init(&env, vec![&env, proposer.clone(), other], 2);
- let id = governance::propose(&env, proposal(&env, 1, proposer.clone()));
- governance::approve(&env, &proposer, id);
- governance::approve(&env, &proposer, id);
-
let contract_id = setup_env(&env);
let proposer = Address::generate(&env);
- let approver = Address::generate(&env);
let signer2 = Address::generate(&env);
-
- env.mock_all_auths();
- let id = env.as_contract(&contract_id, || {
- governance::init(&env, vec![&env, proposer.clone(), signer2.clone()], 1);
- let prop = create_dummy_proposal(&env, &proposer);
- governance::propose(&env, prop)
- });
-
- env.as_contract(&contract_id, || {
- governance::approve(&env, &proposer, id);
- });
-
- env.as_contract(&contract_id, || {
- governance::approve(&env, &signer2, id);
-
env.as_contract(&contract_id, || {
governance::init(&env, vec![&env, proposer.clone(), signer2.clone()], 1);
-
});
let id = propose_default(&env, &contract_id, &proposer);
env.as_contract(&contract_id, || governance::approve(&env, &proposer, id));
@@ -194,24 +117,10 @@ mod tests {
env.mock_all_auths();
let contract_id = setup_env(&env);
let proposer = Address::generate(&env);
- env.mock_all_auths();
-
-
- env.mock_all_auths();
- let id = env.as_contract(&contract_id, || {
- governance::init(&env, vec![&env, proposer.clone()], 2);
- let prop = create_dummy_proposal(&env, &proposer);
- governance::propose(&env, prop)
- });
-
- env.as_contract(&contract_id, || {
- governance::execute(&env, id);
- });
init_one_of_one(&env, &contract_id, &proposer);
let id = propose_default(&env, &contract_id, &proposer);
env.as_contract(&contract_id, || governance::execute(&env, id));
-
}
#[test]
@@ -221,85 +130,35 @@ mod tests {
env.mock_all_auths();
let contract_id = setup_env(&env);
let proposer = Address::generate(&env);
- let approver = Address::generate(&env);
-
-
- env.mock_all_auths();
- let id = env.as_contract(&contract_id, || {
- governance::init(&env, vec![&env, proposer.clone()], 1);
- let prop = create_dummy_proposal(&env, &proposer);
- governance::propose(&env, prop)
- });
-
- env.as_contract(&contract_id, || {
- governance::approve(&env, &proposer, id);
- });
-
- env.ledger().with_mut(|l| l.sequence_number = 1000);
-
- env.as_contract(&contract_id, || {
- governance::execute(&env, id);
- });
-
- env.as_contract(&contract_id, || {
init_one_of_one(&env, &contract_id, &proposer);
let id = propose_default(&env, &contract_id, &proposer);
env.as_contract(&contract_id, || governance::approve(&env, &proposer, id));
env.as_contract(&contract_id, || {
- env.ledger()
- .set_sequence_number(governance::TIMELOCK_LEDGERS + 1);
+ env.ledger().set_sequence_number(governance::TIMELOCK_LEDGERS + 1);
governance::execute(&env, id);
-
governance::execute(&env, id);
-
});
}
#[test]
#[should_panic]
- fn timelock_blocks_early_execution() {
+ fn test_reject_approval_of_executed_proposal() {
let env = Env::default();
env.mock_all_auths();
-
- let contract_id = env.register_contract(None, TestContract);
-
let contract_id = setup_env(&env);
let proposer = Address::generate(&env);
- let approver = Address::generate(&env);
let signer2 = Address::generate(&env);
-
- env.mock_all_auths();
- let id = env.as_contract(&contract_id, || {
- governance::init(&env, vec![&env, proposer.clone(), signer2.clone()], 1);
- let prop = create_dummy_proposal(&env, &proposer);
- governance::propose(&env, prop)
- });
-
- env.as_contract(&contract_id, || {
- governance::approve(&env, &proposer, id);
- });
-
- env.ledger().with_mut(|l| l.sequence_number = 1000);
- env.as_contract(&contract_id, || {
- governance::execute(&env, id);
- });
-
- env.as_contract(&contract_id, || {
- governance::approve(&env, &signer2, id);
-
env.as_contract(&contract_id, || {
governance::init(&env, vec![&env, proposer.clone(), signer2.clone()], 1);
});
let id = propose_default(&env, &contract_id, &proposer);
env.as_contract(&contract_id, || governance::approve(&env, &proposer, id));
env.as_contract(&contract_id, || {
- env.ledger()
- .set_sequence_number(governance::TIMELOCK_LEDGERS + 1);
+ env.ledger().set_sequence_number(governance::TIMELOCK_LEDGERS + 1);
governance::execute(&env, id);
-
});
env.as_contract(&contract_id, || governance::approve(&env, &signer2, id));
}
@@ -309,43 +168,20 @@ mod tests {
let env = Env::default();
env.mock_all_auths();
let contract_id = setup_env(&env);
-
let proposer = Address::generate(&env);
- let approver = Address::generate(&env);
-
-
- env.as_contract(&contract_id, || {
- governance::init(&env, vec![&env, proposer.clone()], 1);
- let id = governance::propose(&env, proposal(&env, 1, proposer.clone()));
- governance::approve(&env, &proposer, id);
- governance::execute(&env, id);
- });
- }
-}
init_one_of_one(&env, &contract_id, &proposer);
let id = propose_default(&env, &contract_id, &proposer);
env.as_contract(&contract_id, || {
- assert_eq!(
- governance::get_proposal(&env, id).state,
- ProposalState::Pending
- );
+ assert_eq!(governance::get_proposal(&env, id).state, ProposalState::Pending);
});
env.as_contract(&contract_id, || governance::approve(&env, &proposer, id));
env.as_contract(&contract_id, || {
- assert_eq!(
- governance::get_proposal(&env, id).state,
- ProposalState::Approved
- );
- env.ledger()
- .set_sequence_number(governance::TIMELOCK_LEDGERS + 1);
-
+ assert_eq!(governance::get_proposal(&env, id).state, ProposalState::Approved);
+ env.ledger().set_sequence_number(governance::TIMELOCK_LEDGERS + 1);
governance::execute(&env, id);
- assert_eq!(
- governance::get_proposal(&env, id).state,
- ProposalState::Executed
- );
+ assert_eq!(governance::get_proposal(&env, id).state, ProposalState::Executed);
});
}
@@ -361,47 +197,29 @@ mod tests {
env.mock_all_auths();
let contract_id = setup_env(&env);
let proposer = Address::generate(&env);
- let signer2 = Address::generate(&env);
-
-
- env.mock_all_auths();
- let id = env.as_contract(&contract_id, || {
- governance::init(&env, vec![&env, proposer.clone()], 2);
- let prop = create_dummy_proposal(&env, &proposer);
- governance::propose(&env, prop)
- });
-
- env.as_contract(&contract_id, || {
- governance::approve(&env, &proposer, id);
- });
-
- env.as_contract(&contract_id, || {
env.as_contract(&contract_id, || {
- governance::init(&env, vec![&env, proposer.clone(), signer2], 2);
+ governance::init(&env, vec![&env, proposer.clone()], 2);
});
let id = propose_default(&env, &contract_id, &proposer);
env.as_contract(&contract_id, || {
governance::approve(&env, &proposer, id);
-
governance::approve(&env, &proposer, id);
});
}
-}
-/// State Transition Matrix (for documentation)
-///
-/// | Current State | Operation | Target State | Allowed | Error |
-/// |---|---|---|---|---|
-/// | Pending | approve (< threshold) | Pending | Yes | — |
-/// | Pending | approve (>= threshold) | Approved | Yes | — |
-/// | Pending | execute | — | No | InvalidStateTransition |
-/// | Approved | approve | — | No | InvalidStateTransition |
-/// | Approved | execute (timelock OK) | Executed | Yes | — |
-/// | Approved | execute (timelock active) | — | No | TimelockActive |
-/// | Executed | approve | — | No | InvalidStateTransition |
-/// | Executed | execute | — | No | InvalidStateTransition |
-#[allow(dead_code)]
-pub struct StateTransitionMatrix;
+ /// State Transition Matrix
+ ///
+ /// | Current State | Operation | Target State | Allowed | Error |
+ /// |---|---|---|---|---|
+ /// | Pending | approve (< threshold) | Pending | Yes | — |
+ /// | Pending | approve (>= threshold) | Approved | Yes | — |
+ /// | Pending | execute | — | No | InvalidStateTransition |
+ /// | Approved | approve | — | No | InvalidStateTransition |
+ /// | Approved | execute (timelock OK) | Executed | Yes | — |
+ /// | Approved | execute (timelock active) | — | No | TimelockActive |
+ /// | Executed | approve | — | No | InvalidStateTransition |
+ /// | Executed | execute | — | No | InvalidStateTransition |
+ #[allow(dead_code)]
+ pub struct StateTransitionMatrix;
}
-
diff --git a/engine-core/src/lib.rs b/engine-core/src/lib.rs
index 1b14ef7..8ae9884 100644
--- a/engine-core/src/lib.rs
+++ b/engine-core/src/lib.rs
@@ -17,9 +17,6 @@ pub mod treasury;
pub mod types;
pub mod upgrade;
pub mod version;
-pub mod event_struct;
-pub mod event_utils;
-pub mod core;
#[cfg(test)]
mod governance_tests;
diff --git a/engine-core/src/protocol_fee.rs b/engine-core/src/protocol_fee.rs
index ec88f07..bce197b 100644
--- a/engine-core/src/protocol_fee.rs
+++ b/engine-core/src/protocol_fee.rs
@@ -1,46 +1,77 @@
+//! Protocol fee calculation and transfer hooks.
-//! Protocol fee calculation and deduction.
-
-use crate::circuit_breaker::assert_closed;
-use crate::event_struct::{ACT_FEE, MOD_FEE};
-use crate::event_utils::publish_event;
-use soroban_sdk::{contracterror, panic_with_error, symbol_short, token, Address, BytesN, Env, String, Symbol};
-
-//! Protocol fee helpers with checked arithmetic.
-
+use crate::burn::reject_zero_address;
use crate::circuit_breaker::assert_closed;
-use crate::event_struct::{ACT_FEE, MOD_FEE};
+use crate::event_struct::{ACT_FEE, ACT_FEE_TRANSFER, MOD_FEE};
use crate::event_utils::{publish_event, zero_hash};
+use crate::guards::ReentrancyGuard;
use soroban_sdk::{
contracterror, panic_with_error, symbol_short, token, Address, Env, String, Symbol,
};
-
-const KEY_FEE_BPS: Symbol = symbol_short!("FEE_BPS");
+const KEY_FEE_BPS: Symbol = symbol_short!("FEE_BPS");
const KEY_FEE_RECIPIENT: Symbol = symbol_short!("FEE_RCP");
+const KEY_TOK_EX: Symbol = symbol_short!("TOK_EX");
+
const MAX_BPS: u32 = 10_000;
const ZERO_ADDRESS: &str = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF";
#[contracterror]
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
-
pub enum FeeError {
- InvalidBasisPoints = 1,
- InvalidRecipient = 2,
+ InvalidBasisPoints = 1,
+ InvalidRecipient = 2,
FeeCalculationOverflow = 3,
- InvalidAmount = 4,
+ InvalidAmount = 4,
}
+// ── Configuration ─────────────────────────────────────────────────────────────
+
+/// Initialise fee configuration. Must be called once during contract setup.
pub fn init(env: &Env, fee_bps: u32, recipient: &Address) {
- validate_bps(env, fee_bps);
+ if fee_bps > MAX_BPS {
+ panic_with_error!(env, FeeError::InvalidBasisPoints);
+ }
validate_address(env, recipient);
+ env.storage().instance().set(&KEY_FEE_BPS, &fee_bps);
+ env.storage().instance().set(&KEY_FEE_RECIPIENT, recipient);
+}
+
+pub fn get_fee_config(env: &Env) -> (u32, Option) {
+ let fee_bps: u32 = env.storage().instance().get(&KEY_FEE_BPS).unwrap_or(0);
+ let recipient: Option = env.storage().instance().get(&KEY_FEE_RECIPIENT);
+ (fee_bps, recipient)
+}
+
+pub fn set_fee_bps(env: &Env, fee_bps: u32) {
+ if fee_bps > MAX_BPS {
+ panic_with_error!(env, FeeError::InvalidBasisPoints);
+ }
env.storage().instance().set(&KEY_FEE_BPS, &fee_bps);
+}
+
+pub fn set_fee_recipient(env: &Env, recipient: &Address) {
+ validate_address(env, recipient);
env.storage().instance().set(&KEY_FEE_RECIPIENT, recipient);
}
+// ── Token exemption ───────────────────────────────────────────────────────────
+
+pub fn set_token_exempt(env: &Env, token: &Address, exempt: bool) {
+ let k = (KEY_TOK_EX, token.clone());
+ if exempt {
+ env.storage().instance().set(&k, &true);
+ } else {
+ env.storage().instance().remove(&k);
+ }
+}
+
+pub fn is_token_exempt(env: &Env, token: &Address) -> bool {
+ env.storage().instance().has(&(KEY_TOK_EX, token.clone()))
+}
+
+// ── Fee calculation ───────────────────────────────────────────────────────────
+
pub fn calculate_fee(env: &Env, amount: i128) -> (i128, i128) {
if amount < 0 {
panic_with_error!(env, FeeError::InvalidAmount);
@@ -51,11 +82,7 @@ pub fn calculate_fee(env: &Env, amount: i128) -> (i128, i128) {
}
let fee = amount
.checked_mul(fee_bps as i128)
-
.and_then(|v| v.checked_div(MAX_BPS as i128))
-
- .and_then(|value| value.checked_div(MAX_BPS as i128))
-
.unwrap_or_else(|| panic_with_error!(env, FeeError::FeeCalculationOverflow));
let net = amount
.checked_sub(fee)
@@ -63,86 +90,101 @@ pub fn calculate_fee(env: &Env, amount: i128) -> (i128, i128) {
(fee, net)
}
-/// Transfer the protocol fee from this contract to the configured recipient.
-pub fn deduct_fee(env: &Env, token: &Address, amount: i128) -> i128 {
- crate::non_reentrant!(env);
+// ── Transfer hooks ────────────────────────────────────────────────────────────
+
+/// Protocol-level fee-on-transfer hook.
+///
+/// Intercepts a transfer of `amount` tokens from `from` to `to` and:
+///
+/// 1. Asserts the circuit breaker is `Closed`.
+/// 2. Acquires the reentrancy guard.
+/// 3. Rejects `to` = zero address.
+/// 4. If `token` is fee-exempt, transfers `amount` from `from` → `to` unchanged.
+/// 5. Otherwise splits the transfer: `fee` → fee recipient, `net` → `to`.
+///
+/// Returns the net amount delivered to `to`.
+pub fn fee_on_transfer(
+ env: &Env,
+ token: &Address,
+ from: &Address,
+ to: &Address,
+ amount: i128,
+) -> i128 {
assert_closed(env);
+ let _guard = ReentrancyGuard::enter(env);
+ reject_zero_address(env, to);
+
+ let tkn = token::Client::new(env, token);
+
+ if is_token_exempt(env, token) {
+ tkn.transfer(from, to, &amount);
+ return amount;
+ }
let (fee, net) = calculate_fee(env, amount);
+
if fee > 0 {
let recipient: Address = env
.storage()
.instance()
.get(&KEY_FEE_RECIPIENT)
.unwrap_or_else(|| panic_with_error!(env, FeeError::InvalidRecipient));
+ tkn.transfer(from, &recipient, &fee);
+ }
- token::Client::new(env, token).transfer(&env.current_contract_address(), &recipient, &fee);
-
-
- publish_event(
- env,
- MOD_FEE | ACT_FEE,
- fee_as_u64(env, fee),
- BytesN::from_array(env, &[0u8; 32]),
- );
-
- if fee > u64::MAX as i128 {
- panic_with_error!(env, FeeError::FeeCalculationOverflow);
- }
- publish_event(env, MOD_FEE | ACT_FEE, fee as u64, zero_hash(env));
-
+ if net > 0 {
+ tkn.transfer(from, to, &net);
}
- net
-}
-pub fn get_fee_config(env: &Env) -> (u32, Option) {
- let fee_bps: u32 = env.storage().instance().get(&KEY_FEE_BPS).unwrap_or(0);
- let recipient: Option = env.storage().instance().get(&KEY_FEE_RECIPIENT);
- (fee_bps, recipient)
-}
+ publish_event(env, MOD_FEE | ACT_FEE_TRANSFER, fee as u64, zero_hash(env));
-pub fn set_fee_bps(env: &Env, fee_bps: u32) {
- validate_bps(env, fee_bps);
- env.storage().instance().set(&KEY_FEE_BPS, &fee_bps);
+ net
}
-pub fn set_fee_recipient(env: &Env, recipient: &Address) {
- validate_address(env, recipient);
- env.storage().instance().set(&KEY_FEE_RECIPIENT, recipient);
-}
+/// Low-level fee deduction from the contract's own token balance.
+///
+/// Transfers the fee portion from `current_contract_address()` to the
+/// configured recipient. Returns the net amount.
+pub fn deduct_fee(env: &Env, token: &Address, amount: i128) -> i128 {
+ crate::non_reentrant!(env);
+ assert_closed(env);
-fn validate_bps(env: &Env, fee_bps: u32) {
- if fee_bps > MAX_BPS {
- panic_with_error!(env, FeeError::InvalidBasisPoints);
+ let (fee, net) = calculate_fee(env, amount);
+ if fee > 0 {
+ let recipient: Address = env
+ .storage()
+ .instance()
+ .get(&KEY_FEE_RECIPIENT)
+ .unwrap_or_else(|| panic_with_error!(env, FeeError::InvalidRecipient));
+ token::Client::new(env, token).transfer(
+ &env.current_contract_address(),
+ &recipient,
+ &fee,
+ );
+ publish_event(env, MOD_FEE | ACT_FEE, fee as u64, zero_hash(env));
}
+ net
}
fn validate_address(env: &Env, addr: &Address) {
-
- if addr.to_string().is_empty() {
- panic_with_error!(env, FeeError::InvalidRecipient);
- }
let zero = String::from_str(env, ZERO_ADDRESS);
if addr.to_string() == zero {
-
- let zero = String::from_str(env, ZERO_ADDRESS);
- if addr.to_string().is_empty() || addr.to_string() == zero {
-
panic_with_error!(env, FeeError::InvalidRecipient);
}
}
-fn fee_as_u64(env: &Env, fee: i128) -> u64 {
- if fee > u64::MAX as i128 {
- panic_with_error!(env, FeeError::FeeCalculationOverflow);
- }
- fee as u64
-}
+// ── Tests ─────────────────────────────────────────────────────────────────────
#[cfg(test)]
mod tests {
use super::*;
- use soroban_sdk::{contract, contractimpl, testutils::Address as _, Env};
+ use soroban_sdk::{
+ contract, contractimpl,
+ testutils::Address as _,
+ token, Env,
+ };
+
+ use crate::circuit_breaker;
#[contract]
pub struct TestContract;
@@ -157,23 +199,40 @@ mod tests {
(contract_id, recipient)
}
+ fn make_token(env: &Env) -> (Address, token::StellarAssetClient) {
+ let admin = Address::generate(env);
+ let addr = env.register_stellar_asset_contract_v2(admin).address();
+ let client = token::StellarAssetClient::new(env, &addr);
+ (addr, client)
+ }
+
+ // ── calculate_fee ─────────────────────────────────────────────────────────
+
+ #[test]
+ fn fee_calculation_zero_bps() {
+ let env = Env::default();
+ let (contract_id, _) = setup(&env, 0);
+ env.as_contract(&contract_id, || {
+ let (fee, net) = calculate_fee(&env, 1_000);
+ assert_eq!(fee, 0);
+ assert_eq!(net, 1_000);
+ });
+ }
+
#[test]
fn fee_calculation_standard() {
let env = Env::default();
let (contract_id, _) = setup(&env, 500);
env.as_contract(&contract_id, || {
- let (fee, net) = calculate_fee(&env, 1000);
+ let (fee, net) = calculate_fee(&env, 1_000);
assert_eq!(fee, 50);
assert_eq!(net, 950);
});
}
#[test]
- fn full_bps_is_full_amount() {
+ fn fee_calculation_fractional_bps() {
let env = Env::default();
-
- let (contract_id, _) = setup(&env, 10_000);
-
let (contract_id, _) = setup(&env, 333);
env.as_contract(&contract_id, || {
let (fee, net) = calculate_fee(&env, 100);
@@ -183,19 +242,30 @@ mod tests {
}
#[test]
- fn fee_at_full_bps_is_full_amount() {
+ fn zero_amount_no_fee() {
let env = Env::default();
- let (contract_id, _) = setup(&env, MAX_BPS);
-
+ let (contract_id, _) = setup(&env, 500);
env.as_contract(&contract_id, || {
- let (fee, net) = calculate_fee(&env, 1000);
- assert_eq!(fee, 1000);
+ let (fee, net) = calculate_fee(&env, 0);
+ assert_eq!(fee, 0);
assert_eq!(net, 0);
});
}
#[test]
+ fn fee_at_full_bps_is_full_amount() {
+ let env = Env::default();
+ let (contract_id, _) = setup(&env, 10_000);
+ env.as_contract(&contract_id, || {
+ let (fee, net) = calculate_fee(&env, 1_000);
+ assert_eq!(fee, 1_000);
+ assert_eq!(net, 0);
+ });
+ }
+
+ // ── get/set config ────────────────────────────────────────────────────────
+ #[test]
fn get_fee_config_returns_stored_values() {
let env = Env::default();
let (contract_id, recipient) = setup(&env, 250);
@@ -218,16 +288,186 @@ mod tests {
}
#[test]
+ fn set_fee_recipient_updates_address() {
+ let env = Env::default();
+ let (contract_id, _) = setup(&env, 100);
+ let new_recipient = Address::generate(&env);
+ env.as_contract(&contract_id, || {
+ set_fee_recipient(&env, &new_recipient);
+ let (_, rec) = get_fee_config(&env);
+ assert_eq!(rec.unwrap(), new_recipient);
+ });
+ }
+ #[test]
#[should_panic]
fn rejects_bps_over_max() {
let env = Env::default();
let contract_id = env.register_contract(None, TestContract);
let recipient = Address::generate(&env);
+ env.as_contract(&contract_id, || init(&env, MAX_BPS + 1, &recipient));
+ }
- env.as_contract(&contract_id, || init(&env, 10_001, &recipient));
+ // ── token exemption ───────────────────────────────────────────────────────
- env.as_contract(&contract_id, || init(&env, MAX_BPS + 1, &recipient));
+ #[test]
+ fn token_exempt_false_by_default() {
+ let env = Env::default();
+ let (contract_id, _) = setup(&env, 500);
+ let token = Address::generate(&env);
+ env.as_contract(&contract_id, || {
+ assert!(!is_token_exempt(&env, &token));
+ });
+ }
+
+ #[test]
+ fn token_exempt_set_and_check() {
+ let env = Env::default();
+ let (contract_id, _) = setup(&env, 500);
+ let token = Address::generate(&env);
+ env.as_contract(&contract_id, || {
+ set_token_exempt(&env, &token, true);
+ assert!(is_token_exempt(&env, &token));
+ });
+ }
+
+ #[test]
+ fn token_exempt_cleared() {
+ let env = Env::default();
+ let (contract_id, _) = setup(&env, 500);
+ let token = Address::generate(&env);
+ env.as_contract(&contract_id, || {
+ set_token_exempt(&env, &token, true);
+ set_token_exempt(&env, &token, false);
+ assert!(!is_token_exempt(&env, &token));
+ });
+ }
+
+ #[test]
+ fn multiple_tokens_exempt_independently() {
+ let env = Env::default();
+ let (contract_id, _) = setup(&env, 500);
+ let token_a = Address::generate(&env);
+ let token_b = Address::generate(&env);
+ env.as_contract(&contract_id, || {
+ set_token_exempt(&env, &token_a, true);
+ assert!(is_token_exempt(&env, &token_a));
+ assert!(!is_token_exempt(&env, &token_b));
+ });
+ }
+
+ // ── fee_on_transfer ───────────────────────────────────────────────────────
+
+ #[test]
+ #[should_panic]
+ fn fee_on_transfer_circuit_open_panics() {
+ let env = Env::default();
+ env.mock_all_auths();
+ let (contract_id, _) = setup(&env, 500);
+ let token = Address::generate(&env);
+ let from = Address::generate(&env);
+ let to = Address::generate(&env);
+ let guardian = Address::generate(&env);
+
+ env.as_contract(&contract_id, || {
+ use soroban_sdk::vec;
+ circuit_breaker::init(&env, vec![&env, guardian.clone()]);
+ circuit_breaker::trip(&env, &guardian);
+ fee_on_transfer(&env, &token, &from, &to, 1_000);
+ });
+ }
+
+ #[test]
+ fn fee_on_transfer_standard_fee_splits_correctly() {
+ let env = Env::default();
+ env.mock_all_auths_allowing_non_root_auth();
+
+ let (token_addr, stellar) = make_token(&env);
+ let (contract_id, fee_recipient) = setup(&env, 500); // 5 %
+
+ let from = Address::generate(&env);
+ let to = Address::generate(&env);
+ stellar.mint(&from, &1_000i128);
+
+ let net = env.as_contract(&contract_id, || {
+ fee_on_transfer(&env, &token_addr, &from, &to, 1_000)
+ });
+
+ let tkn = token::Client::new(&env, &token_addr);
+ assert_eq!(net, 950);
+ assert_eq!(tkn.balance(&to), 950);
+ assert_eq!(tkn.balance(&fee_recipient), 50);
+ assert_eq!(tkn.balance(&from), 0);
+ }
+
+ #[test]
+ fn fee_on_transfer_zero_bps_passes_full_amount() {
+ let env = Env::default();
+ env.mock_all_auths_allowing_non_root_auth();
+
+ let (token_addr, stellar) = make_token(&env);
+ let (contract_id, _) = setup(&env, 0);
+
+ let from = Address::generate(&env);
+ let to = Address::generate(&env);
+ stellar.mint(&from, &500i128);
+
+ let net = env.as_contract(&contract_id, || {
+ fee_on_transfer(&env, &token_addr, &from, &to, 500)
+ });
+
+ let tkn = token::Client::new(&env, &token_addr);
+ assert_eq!(net, 500);
+ assert_eq!(tkn.balance(&to), 500);
+ assert_eq!(tkn.balance(&from), 0);
+ }
+
+ #[test]
+ fn fee_on_transfer_exempt_token_no_fee_deducted() {
+ let env = Env::default();
+ env.mock_all_auths_allowing_non_root_auth();
+
+ let (token_addr, stellar) = make_token(&env);
+ let (contract_id, fee_recipient) = setup(&env, 500); // 5 % — but token is exempt
+
+ let from = Address::generate(&env);
+ let to = Address::generate(&env);
+ stellar.mint(&from, &1_000i128);
+
+ env.as_contract(&contract_id, || {
+ set_token_exempt(&env, &token_addr, true);
+ });
+
+ let net = env.as_contract(&contract_id, || {
+ fee_on_transfer(&env, &token_addr, &from, &to, 1_000)
+ });
+
+ let tkn = token::Client::new(&env, &token_addr);
+ assert_eq!(net, 1_000);
+ assert_eq!(tkn.balance(&to), 1_000);
+ assert_eq!(tkn.balance(&fee_recipient), 0);
+ assert_eq!(tkn.balance(&from), 0);
+ }
+
+ #[test]
+ fn fee_on_transfer_full_bps_all_goes_to_recipient() {
+ let env = Env::default();
+ env.mock_all_auths_allowing_non_root_auth();
+
+ let (token_addr, stellar) = make_token(&env);
+ let (contract_id, fee_recipient) = setup(&env, 10_000); // 100 %
+
+ let from = Address::generate(&env);
+ let to = Address::generate(&env);
+ stellar.mint(&from, &200i128);
+
+ let net = env.as_contract(&contract_id, || {
+ fee_on_transfer(&env, &token_addr, &from, &to, 200)
+ });
+ let tkn = token::Client::new(&env, &token_addr);
+ assert_eq!(net, 0);
+ assert_eq!(tkn.balance(&fee_recipient), 200);
+ assert_eq!(tkn.balance(&from), 0);
}
}
diff --git a/engine-core/src/reentrancy_tests.rs b/engine-core/src/reentrancy_tests.rs
index f8eb72f..82c76d2 100644
--- a/engine-core/src/reentrancy_tests.rs
+++ b/engine-core/src/reentrancy_tests.rs
@@ -2,14 +2,9 @@
#[cfg(test)]
mod tests {
-
use crate::guards::{enter_reentrancy_guard, exit_reentrancy_guard};
use soroban_sdk::{contract, contractimpl, Env};
- use crate::guards::enter_reentrancy_guard;
- use soroban_sdk::{contract, contractimpl, Address, Env};
-
-
#[contract]
pub struct TestContract;
diff --git a/engine-core/src/treasury.rs b/engine-core/src/treasury.rs
index 521b993..3b61fda 100644
--- a/engine-core/src/treasury.rs
+++ b/engine-core/src/treasury.rs
@@ -1,8 +1,6 @@
//! Treasury state snapshots and outflow time-locking.
-
use crate::circuit_breaker::assert_closed;
-
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};
@@ -12,56 +10,45 @@ use soroban_sdk::{
};
const KEY_SNAP_COUNTER: Symbol = symbol_short!("SNAPC");
-const KEY_SNAP_LATEST: Symbol = symbol_short!("SNAPL");
-const KEY_OUTFLOWS: Symbol = symbol_short!("OUTFLOWS");
+const KEY_SNAP_LATEST: Symbol = symbol_short!("SNAPL");
+const KEY_OUTFLOWS: Symbol = symbol_short!("OUTFLOWS");
-const MAX_BALANCE: i128 = 1_000_000_000_000_000_000;
+const MAX_BALANCE: i128 = 1_000_000_000_000_000_000;
const MAX_ACCOUNT_COUNT: u32 = 10_000_000;
pub const OUTFLOW_TIMELOCK_SECONDS: u64 = 24 * 60 * 60;
-
/// About 7 days at 5-second ledger time, enough for off-chain indexer pickup.
-
-/// Temporary storage TTL constants (ledgers).
-
const SNAP_TTL_THRESHOLD: u32 = 17_280;
const SNAP_TTL_EXTEND_TO: u32 = 17_280 * 7;
#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
-
-pub enum TreasuryKey {
-
enum TreasuryKey {
-
Snapshot(u64),
}
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub enum TreasuryError {
- SnapshotNotFound = 1,
- InvalidBalance = 2,
- InvalidAccountCount = 3,
- InvalidOutflowAmount = 4,
- OutflowNotFound = 5,
+ SnapshotNotFound = 1,
+ InvalidBalance = 2,
+ InvalidAccountCount = 3,
+ InvalidOutflowAmount = 4,
+ OutflowNotFound = 5,
OutflowAlreadyExecuted = 6,
- TimelockActive = 7,
-
- DuplicateOutflow = 8,
-
- ArithmeticOverflow = 8,
-
+ TimelockActive = 7,
+ ArithmeticOverflow = 8,
+ DuplicateOutflow = 9,
}
#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct TimelockedOutflow {
- pub id: u64,
- pub amount: i128,
- pub requested_at: u64,
+ pub id: u64,
+ pub amount: i128,
+ pub requested_at: u64,
pub executable_at: u64,
- pub executed: bool,
+ pub executed: bool,
}
pub fn init(env: &Env) {
@@ -75,7 +62,6 @@ pub fn init(env: &Env) {
/// Queue a treasury outflow behind the mandatory 24-hour delay.
pub fn schedule_outflow(env: &Env, outflow_id: u64, amount: i128) -> u64 {
crate::non_reentrant!(env);
-
assert_closed(env);
if amount <= 0 {
@@ -108,7 +94,6 @@ 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 {
crate::non_reentrant!(env);
-
assert_closed(env);
let mut outflows = load_outflows(env);
@@ -127,12 +112,7 @@ pub fn execute_outflow(env: &Env, outflow_id: u64) -> TimelockedOutflow {
outflows.set(outflow_id, outflow.clone());
env.storage().instance().set(&KEY_OUTFLOWS, &outflows);
- publish_event(
- env,
- MOD_TREASURY | ACT_TRIGGERED,
- outflow_id,
- zero_hash(env),
- );
+ publish_event(env, MOD_TREASURY | ACT_TRIGGERED, outflow_id, zero_hash(env));
outflow
}
@@ -140,11 +120,7 @@ pub fn get_outflow(env: &Env, outflow_id: u64) -> Option {
load_outflows(env).get(outflow_id)
}
-
-/// Record a treasury snapshot and return its ID.
-
/// Record a treasury snapshot and return its monotonic snapshot id.
-
pub fn record_snapshot(
env: &Env,
total_balance: i128,
@@ -153,15 +129,12 @@ pub fn record_snapshot(
context: Map,
) -> u64 {
crate::non_reentrant!(env);
-
assert_closed(env);
if total_balance < 0 {
panic_with_error!(env, TreasuryError::InvalidBalance);
}
- // Preserve the repository's prior numeric-clamping behaviour while keeping
- // arithmetic checked around counters and timestamps.
let total_balance = total_balance.min(MAX_BALANCE);
let account_count = account_count.min(MAX_ACCOUNT_COUNT);
@@ -183,19 +156,13 @@ pub fn record_snapshot(
context,
};
-
- let snapshot_key = make_snap_key(snapshot_id);
-
let snapshot_key = TreasuryKey::Snapshot(snapshot_id);
-
env.storage().temporary().set(&snapshot_key, &snapshot);
env.storage()
.temporary()
.extend_ttl(&snapshot_key, SNAP_TTL_THRESHOLD, SNAP_TTL_EXTEND_TO);
- env.storage()
- .instance()
- .set(&KEY_SNAP_COUNTER, &snapshot_id);
+ env.storage().instance().set(&KEY_SNAP_COUNTER, &snapshot_id);
env.storage().instance().set(&KEY_SNAP_LATEST, &snapshot_id);
publish_event(env, MOD_TREASURY | ACT_SNAPSHOT, snapshot_id, state_hash);
@@ -203,14 +170,7 @@ pub fn record_snapshot(
}
pub fn get_snapshot(env: &Env, snapshot_id: u64) -> Option {
-
- let key = make_snap_key(snapshot_id);
- env.storage().temporary().get(&key)
-
- env.storage()
- .temporary()
- .get(&TreasuryKey::Snapshot(snapshot_id))
-
+ env.storage().temporary().get(&TreasuryKey::Snapshot(snapshot_id))
}
pub fn get_latest_snapshot(env: &Env) -> Option {
@@ -230,10 +190,7 @@ pub fn get_recent_snapshots(env: &Env, count: u32) -> Vec {
let total = snapshot_count(env);
let mut result = Vec::new(env);
- if total == 0 || count == 0 {
-
if count == 0 || total == 0 {
-
return result;
}
@@ -264,16 +221,10 @@ pub fn audit_trail(env: &Env, from_id: u64) -> Vec {
return result;
}
- let start = from_id.max(1).min(total);
- for id in start..=total {
- if let Some(snap) = get_snapshot(env, id) {
- result.push_back(snap);
-
let start = if from_id == 0 { 1 } else { from_id.min(total) };
for id in start..=total {
if let Some(snapshot) = get_snapshot(env, id) {
result.push_back(snapshot);
-
}
}
result
@@ -294,25 +245,11 @@ fn compute_hash(env: &Env, balance: i128, account_count: u32, ledger: u32) -> By
env.crypto().sha256(&Bytes::from_slice(env, &raw)).into()
}
-
-fn make_snap_key(id: u64) -> TreasuryKey {
- TreasuryKey::Snapshot(id)
-}
-
#[cfg(test)]
mod tests {
use super::*;
use soroban_sdk::{contract, contractimpl, testutils::Ledger as _, Env, Map, Symbol};
-#[cfg(test)]
-mod tests {
- use super::*;
-
- use soroban_sdk::{testutils::Ledger as _, Env, Map, Symbol, testutils::Address as _};
-
- use soroban_sdk::{testutils::Ledger as _, Env, Map, Symbol};
-
-
#[contract]
pub struct TestContract;
@@ -351,12 +288,12 @@ mod tests {
}
#[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() {
+ with_treasury_env(|env| {
+ assert!(get_latest_snapshot(env).is_none());
+ assert_eq!(snapshot_count(env), 0);
+ });
+ }
#[test]
#[should_panic]
diff --git a/engine-core/test_snapshots/audit/tests/hash_mismatch_is_rejected.1.json b/engine-core/test_snapshots/audit/tests/hash_mismatch_is_rejected.1.json
new file mode 100644
index 0000000..93e1abe
--- /dev/null
+++ b/engine-core/test_snapshots/audit/tests/hash_mismatch_is_rejected.1.json
@@ -0,0 +1,131 @@
+{
+ "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": 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_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 2
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/burn/tests/invalid_amount_rejected.1.json b/engine-core/test_snapshots/burn/tests/invalid_amount_rejected.1.json
new file mode 100644
index 0000000..93e1abe
--- /dev/null
+++ b/engine-core/test_snapshots/burn/tests/invalid_amount_rejected.1.json
@@ -0,0 +1,131 @@
+{
+ "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": 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_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 2
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/circuit_breaker/tests/empty_guardian_set_rejected.1.json b/engine-core/test_snapshots/circuit_breaker/tests/empty_guardian_set_rejected.1.json
new file mode 100644
index 0000000..bb80bbb
--- /dev/null
+++ b/engine-core/test_snapshots/circuit_breaker/tests/empty_guardian_set_rejected.1.json
@@ -0,0 +1,131 @@
+{
+ "generators": {
+ "address": 1,
+ "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": 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_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 4
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 4
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 4
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/core/tests/test_batch_update_param_success.1.json b/engine-core/test_snapshots/core/tests/test_batch_update_param_success.1.json
index 93fcef1..147167f 100644
--- a/engine-core/test_snapshots/core/tests/test_batch_update_param_success.1.json
+++ b/engine-core/test_snapshots/core/tests/test_batch_update_param_success.1.json
@@ -1,10 +1,9 @@
{
"generators": {
- "address": 3,
+ "address": 2,
"nonce": 0
},
"auth": [
- [],
[
[
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
@@ -12,82 +11,21 @@
"function": {
"contract_fn": {
"contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
- "function_name": "batch_update_param",
+ "function_name": "initialize",
"args": [
{
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
- },
- {
- "vec": [
- {
- "vec": [
- {
- "symbol": "FEE1"
- },
- {
- "u64": 100
- }
- ]
- },
- {
- "vec": [
- {
- "symbol": "FEE2"
- },
- {
- "u64": 200
- }
- ]
- }
- ]
- },
- {
- "map": [
- {
- "key": {
- "symbol": "author"
- },
- "val": {
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
- }
- },
- {
- "key": {
- "symbol": "ledger"
- },
- "val": {
- "u32": 101
- }
- },
- {
- "key": {
- "symbol": "sequence"
- },
- "val": {
- "u64": 2
- }
- },
- {
- "key": {
- "symbol": "state_hash"
- },
- "val": {
- "bytes": "4e8e1d41197ef7a08d5b52417f8128512def2b8ecfecebcdfe6b6ef818908a24"
- }
- }
- ]
- },
- {
- "bytes": "0202020202020202020202020202020202020202020202020202020202020202"
}
]
}
},
"sub_invocations": []
}
- ],
+ ]
+ ],
+ [
[
- "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
{
"function": {
"contract_fn": {
@@ -128,7 +66,7 @@
"symbol": "author"
},
"val": {
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
}
},
{
@@ -209,6 +147,14 @@
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
}
},
+ {
+ "key": {
+ "symbol": "CP_INIT"
+ },
+ "val": {
+ "bool": true
+ }
+ },
{
"key": {
"symbol": "FEE1"
@@ -233,6 +179,14 @@
"bytes": "4e8e1d41197ef7a08d5b52417f8128512def2b8ecfecebcdfe6b6ef818908a24"
}
},
+ {
+ "key": {
+ "symbol": "P_COUNT"
+ },
+ "val": {
+ "u64": 0
+ }
+ },
{
"key": {
"symbol": "SEQ"
@@ -287,7 +241,7 @@
[
{
"contract_data": {
- "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 5541220902715666415
@@ -302,7 +256,7 @@
"data": {
"contract_data": {
"ext": "v0",
- "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 5541220902715666415
@@ -442,7 +396,7 @@
"symbol": "author"
},
"val": {
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
}
},
{
diff --git a/engine-core/test_snapshots/core/tests/test_get_admin_rejects_uninitialized.1.json b/engine-core/test_snapshots/core/tests/test_get_admin_rejects_uninitialized.1.json
new file mode 100644
index 0000000..cada583
--- /dev/null
+++ b/engine-core/test_snapshots/core/tests/test_get_admin_rejects_uninitialized.1.json
@@ -0,0 +1,242 @@
+{
+ "generators": {
+ "address": 1,
+ "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": 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": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "get_admin"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 3
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 3
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 3
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 3
+ }
+ }
+ ],
+ "data": {
+ "string": "caught error from function"
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 3
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "contract call failed"
+ },
+ {
+ "symbol": "get_admin"
+ },
+ {
+ "vec": []
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 3
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/core/tests/test_initialize.1.json b/engine-core/test_snapshots/core/tests/test_initialize.1.json
index 1223943..1674d56 100644
--- a/engine-core/test_snapshots/core/tests/test_initialize.1.json
+++ b/engine-core/test_snapshots/core/tests/test_initialize.1.json
@@ -4,6 +4,25 @@
"nonce": 0
},
"auth": [
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "function_name": "initialize",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
[],
[]
],
@@ -47,6 +66,22 @@
"val": {
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
}
+ },
+ {
+ "key": {
+ "symbol": "CP_INIT"
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "symbol": "P_COUNT"
+ },
+ "val": {
+ "u64": 0
+ }
}
]
}
@@ -58,6 +93,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": {
@@ -129,6 +197,53 @@
},
"failed_call": false
},
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "get_admin"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "get_admin"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
{
"event": {
"ext": "v0",
diff --git a/engine-core/test_snapshots/core/tests/test_update_param_rejects_bad_hash.1.json b/engine-core/test_snapshots/core/tests/test_update_param_rejects_bad_hash.1.json
new file mode 100644
index 0000000..e3cf2cd
--- /dev/null
+++ b/engine-core/test_snapshots/core/tests/test_update_param_rejects_bad_hash.1.json
@@ -0,0 +1,489 @@
+{
+ "generators": {
+ "address": 2,
+ "nonce": 0
+ },
+ "auth": [
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "function_name": "initialize",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ "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": "ADMIN"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "CP_INIT"
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "symbol": "P_COUNT"
+ },
+ "val": {
+ "u64": 0
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "initialize"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "initialize"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "update_param"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "symbol": "FEE"
+ },
+ {
+ "u64": 100
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "0909090909090909090909090909090909090909090909090909090909090909"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0303030303030303030303030303030303030303030303030303030303030303"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 2
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "string": "caught error from function"
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "contract try_call failed"
+ },
+ {
+ "symbol": "update_param"
+ },
+ {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "symbol": "FEE"
+ },
+ {
+ "u64": 100
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "0909090909090909090909090909090909090909090909090909090909090909"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0303030303030303030303030303030303030303030303030303030303030303"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "get_param"
+ }
+ ],
+ "data": {
+ "symbol": "FEE"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "get_param"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/core/tests/test_update_param_rejects_replayed_commitment.1.json b/engine-core/test_snapshots/core/tests/test_update_param_rejects_replayed_commitment.1.json
new file mode 100644
index 0000000..17b29ff
--- /dev/null
+++ b/engine-core/test_snapshots/core/tests/test_update_param_rejects_replayed_commitment.1.json
@@ -0,0 +1,764 @@
+{
+ "generators": {
+ "address": 2,
+ "nonce": 0
+ },
+ "auth": [
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "function_name": "initialize",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "function_name": "update_param",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "symbol": "FEE"
+ },
+ {
+ "u64": 100
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "4d091adc17b45c0c5bba796f6ae531f7cd526610e29957c40f36799e8c47c4bf"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0202020202020202020202020202020202020202020202020202020202020202"
+ }
+ ]
+ }
+ },
+ "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": "ADMIN"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "CP_INIT"
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE"
+ },
+ "val": {
+ "u64": 100
+ }
+ },
+ {
+ "key": {
+ "symbol": "LASTPAR"
+ },
+ "val": {
+ "symbol": "FEE"
+ }
+ },
+ {
+ "key": {
+ "symbol": "PREV_H"
+ },
+ "val": {
+ "bytes": "4d091adc17b45c0c5bba796f6ae531f7cd526610e29957c40f36799e8c47c4bf"
+ }
+ },
+ {
+ "key": {
+ "symbol": "P_COUNT"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "SEQ"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "initialize"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "initialize"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "update_param"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "symbol": "FEE"
+ },
+ {
+ "u64": 100
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "4d091adc17b45c0c5bba796f6ae531f7cd526610e29957c40f36799e8c47c4bf"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0202020202020202020202020202020202020202020202020202020202020202"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 257
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "4d091adc17b45c0c5bba796f6ae531f7cd526610e29957c40f36799e8c47c4bf"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "update_param"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "update_param"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "symbol": "FEE"
+ },
+ {
+ "u64": 200
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "4d091adc17b45c0c5bba796f6ae531f7cd526610e29957c40f36799e8c47c4bf"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0202020202020202020202020202020202020202020202020202020202020202"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 1
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "string": "caught error from function"
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "contract try_call failed"
+ },
+ {
+ "symbol": "update_param"
+ },
+ {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "symbol": "FEE"
+ },
+ {
+ "u64": 200
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "4d091adc17b45c0c5bba796f6ae531f7cd526610e29957c40f36799e8c47c4bf"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0202020202020202020202020202020202020202020202020202020202020202"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "get_param"
+ }
+ ],
+ "data": {
+ "symbol": "FEE"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "get_param"
+ }
+ ],
+ "data": {
+ "u64": 100
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/core/tests/test_update_param_requires_admin.1.json b/engine-core/test_snapshots/core/tests/test_update_param_requires_admin.1.json
new file mode 100644
index 0000000..0494037
--- /dev/null
+++ b/engine-core/test_snapshots/core/tests/test_update_param_requires_admin.1.json
@@ -0,0 +1,489 @@
+{
+ "generators": {
+ "address": 3,
+ "nonce": 0
+ },
+ "auth": [
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "function_name": "initialize",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ "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": "ADMIN"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "CP_INIT"
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "symbol": "P_COUNT"
+ },
+ "val": {
+ "u64": 0
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "initialize"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "initialize"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "update_param"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
+ },
+ {
+ "symbol": "FEE"
+ },
+ {
+ "u64": 100
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "33b17a720159c724cbded2b74624dc582c4aff2ee91fa6fa0fcca4c589356812"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0404040404040404040404040404040404040404040404040404040404040404"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 2
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "string": "caught error from function"
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "contract try_call failed"
+ },
+ {
+ "symbol": "update_param"
+ },
+ {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
+ },
+ {
+ "symbol": "FEE"
+ },
+ {
+ "u64": 100
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "33b17a720159c724cbded2b74624dc582c4aff2ee91fa6fa0fcca4c589356812"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0404040404040404040404040404040404040404040404040404040404040404"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "get_param"
+ }
+ ],
+ "data": {
+ "symbol": "FEE"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "get_param"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/core/tests/test_update_param_success.1.json b/engine-core/test_snapshots/core/tests/test_update_param_success.1.json
index cf9728c..dcaff12 100644
--- a/engine-core/test_snapshots/core/tests/test_update_param_success.1.json
+++ b/engine-core/test_snapshots/core/tests/test_update_param_success.1.json
@@ -1,10 +1,9 @@
{
"generators": {
- "address": 3,
+ "address": 2,
"nonce": 0
},
"auth": [
- [],
[
[
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
@@ -12,64 +11,22 @@
"function": {
"contract_fn": {
"contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
- "function_name": "update_param",
+ "function_name": "initialize",
"args": [
{
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
- },
- {
- "symbol": "FEE"
- },
- {
- "u64": 100
- },
- {
- "map": [
- {
- "key": {
- "symbol": "author"
- },
- "val": {
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
- }
- },
- {
- "key": {
- "symbol": "ledger"
- },
- "val": {
- "u32": 100
- }
- },
- {
- "key": {
- "symbol": "sequence"
- },
- "val": {
- "u64": 1
- }
- },
- {
- "key": {
- "symbol": "state_hash"
- },
- "val": {
- "bytes": "a7cf31387e6255cca069e8ab8f1a9c043304c06167b6ba643279651b406f1475"
- }
- }
- ]
- },
- {
- "bytes": "0101010101010101010101010101010101010101010101010101010101010101"
}
]
}
},
"sub_invocations": []
}
- ],
+ ]
+ ],
+ [],
+ [
[
- "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
{
"function": {
"contract_fn": {
@@ -92,7 +49,7 @@
"symbol": "author"
},
"val": {
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
}
},
{
@@ -100,7 +57,7 @@
"symbol": "ledger"
},
"val": {
- "u32": 100
+ "u32": 0
}
},
{
@@ -130,7 +87,11 @@
"sub_invocations": []
}
]
- ]
+ ],
+ [],
+ [],
+ [],
+ []
],
"ledger": {
"protocol_version": 21,
@@ -173,6 +134,14 @@
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
}
},
+ {
+ "key": {
+ "symbol": "CP_INIT"
+ },
+ "val": {
+ "bool": true
+ }
+ },
{
"key": {
"symbol": "FEE"
@@ -181,6 +150,14 @@
"u64": 100
}
},
+ {
+ "key": {
+ "symbol": "LASTPAR"
+ },
+ "val": {
+ "symbol": "FEE"
+ }
+ },
{
"key": {
"symbol": "PREV_H"
@@ -189,6 +166,14 @@
"bytes": "a7cf31387e6255cca069e8ab8f1a9c043304c06167b6ba643279651b406f1475"
}
},
+ {
+ "key": {
+ "symbol": "P_COUNT"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
{
"key": {
"symbol": "SEQ"
@@ -243,7 +228,7 @@
[
{
"contract_data": {
- "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 5541220902715666415
@@ -258,7 +243,7 @@
"data": {
"contract_data": {
"ext": "v0",
- "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 5541220902715666415
@@ -344,6 +329,95 @@
},
"failed_call": false
},
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "integrity_check"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "a7cf31387e6255cca069e8ab8f1a9c043304c06167b6ba643279651b406f1475"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0101010101010101010101010101010101010101010101010101010101010101"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "integrity_check"
+ }
+ ],
+ "data": {
+ "bool": true
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
{
"event": {
"ext": "v0",
@@ -380,7 +454,7 @@
"symbol": "author"
},
"val": {
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
}
},
{
@@ -388,7 +462,7 @@
"symbol": "ledger"
},
"val": {
- "u32": 100
+ "u32": 0
}
},
{
@@ -487,6 +561,196 @@
}
},
"failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "get_param"
+ }
+ ],
+ "data": {
+ "symbol": "FEE"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "get_param"
+ }
+ ],
+ "data": {
+ "u64": 100
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "param_update_count"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "param_update_count"
+ }
+ ],
+ "data": {
+ "u64": 1
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "last_audit_sequence"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "last_audit_sequence"
+ }
+ ],
+ "data": {
+ "u64": 1
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "state_hash"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "state_hash"
+ }
+ ],
+ "data": {
+ "bytes": "a7cf31387e6255cca069e8ab8f1a9c043304c06167b6ba643279651b406f1475"
+ }
+ }
+ }
+ },
+ "failed_call": false
}
]
}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/core/tests/test_zk_proof_registration_for_current_state_root.1.json b/engine-core/test_snapshots/core/tests/test_zk_proof_registration_for_current_state_root.1.json
new file mode 100644
index 0000000..6d09116
--- /dev/null
+++ b/engine-core/test_snapshots/core/tests/test_zk_proof_registration_for_current_state_root.1.json
@@ -0,0 +1,777 @@
+{
+ "generators": {
+ "address": 2,
+ "nonce": 0
+ },
+ "auth": [
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "function_name": "initialize",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "function_name": "update_param",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "symbol": "FEE"
+ },
+ {
+ "u64": 100
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "2cdcb157c7663f079074f47bee50172abe05f3ef8c06987aeb2f1d8bcc1c8221"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0505050505050505050505050505050505050505050505050505050505050505"
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "function_name": "register_proof",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "bytes": "2cdcb157c7663f079074f47bee50172abe05f3ef8c06987aeb2f1d8bcc1c8221"
+ },
+ {
+ "bytes": "0707070707070707070707070707070707070707070707070707070707070707"
+ },
+ {
+ "u32": 0
+ },
+ {
+ "map": []
+ }
+ ]
+ }
+ },
+ "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": "ADMIN"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "CP_INIT"
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE"
+ },
+ "val": {
+ "u64": 100
+ }
+ },
+ {
+ "key": {
+ "symbol": "LASTPAR"
+ },
+ "val": {
+ "symbol": "FEE"
+ }
+ },
+ {
+ "key": {
+ "symbol": "PREV_H"
+ },
+ "val": {
+ "bytes": "2cdcb157c7663f079074f47bee50172abe05f3ef8c06987aeb2f1d8bcc1c8221"
+ }
+ },
+ {
+ "key": {
+ "symbol": "P_COUNT"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "SEQ"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "ZK_COUNT"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Attestation"
+ },
+ {
+ "bytes": "2cdcb157c7663f079074f47bee50172abe05f3ef8c06987aeb2f1d8bcc1c8221"
+ }
+ ]
+ },
+ "val": {
+ "map": [
+ {
+ "key": {
+ "symbol": "block_seq"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "metadata"
+ },
+ "val": {
+ "map": []
+ }
+ },
+ {
+ "key": {
+ "symbol": "proof_hash"
+ },
+ "val": {
+ "bytes": "0707070707070707070707070707070707070707070707070707070707070707"
+ }
+ },
+ {
+ "key": {
+ "symbol": "registered_at_ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_root"
+ },
+ "val": {
+ "bytes": "2cdcb157c7663f079074f47bee50172abe05f3ef8c06987aeb2f1d8bcc1c8221"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Proof"
+ },
+ {
+ "bytes": "2cdcb157c7663f079074f47bee50172abe05f3ef8c06987aeb2f1d8bcc1c8221"
+ }
+ ]
+ },
+ "val": {
+ "bytes": "0707070707070707070707070707070707070707070707070707070707070707"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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": 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": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": [
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "initialize"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "initialize"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "update_param"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "symbol": "FEE"
+ },
+ {
+ "u64": 100
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "2cdcb157c7663f079074f47bee50172abe05f3ef8c06987aeb2f1d8bcc1c8221"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0505050505050505050505050505050505050505050505050505050505050505"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 257
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "2cdcb157c7663f079074f47bee50172abe05f3ef8c06987aeb2f1d8bcc1c8221"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "update_param"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "register_proof"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "bytes": "2cdcb157c7663f079074f47bee50172abe05f3ef8c06987aeb2f1d8bcc1c8221"
+ },
+ {
+ "bytes": "0707070707070707070707070707070707070707070707070707070707070707"
+ },
+ {
+ "u32": 0
+ },
+ {
+ "map": []
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 257
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0707070707070707070707070707070707070707070707070707070707070707"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 0
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "register_proof"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "get_proof"
+ }
+ ],
+ "data": {
+ "bytes": "2cdcb157c7663f079074f47bee50172abe05f3ef8c06987aeb2f1d8bcc1c8221"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "get_proof"
+ }
+ ],
+ "data": {
+ "bytes": "0707070707070707070707070707070707070707070707070707070707070707"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/core/tests/test_zk_proof_rejects_wrong_state_root.1.json b/engine-core/test_snapshots/core/tests/test_zk_proof_rejects_wrong_state_root.1.json
new file mode 100644
index 0000000..756bbb8
--- /dev/null
+++ b/engine-core/test_snapshots/core/tests/test_zk_proof_rejects_wrong_state_root.1.json
@@ -0,0 +1,648 @@
+{
+ "generators": {
+ "address": 2,
+ "nonce": 0
+ },
+ "auth": [
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "function_name": "initialize",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "function_name": "update_param",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "symbol": "FEE"
+ },
+ {
+ "u64": 100
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "284c0039d44629af44654b24c8c9aee1b033da7d16c37cf01135e985b5c79ba8"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0606060606060606060606060606060606060606060606060606060606060606"
+ }
+ ]
+ }
+ },
+ "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": "ADMIN"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "CP_INIT"
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE"
+ },
+ "val": {
+ "u64": 100
+ }
+ },
+ {
+ "key": {
+ "symbol": "LASTPAR"
+ },
+ "val": {
+ "symbol": "FEE"
+ }
+ },
+ {
+ "key": {
+ "symbol": "PREV_H"
+ },
+ "val": {
+ "bytes": "284c0039d44629af44654b24c8c9aee1b033da7d16c37cf01135e985b5c79ba8"
+ }
+ },
+ {
+ "key": {
+ "symbol": "P_COUNT"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "SEQ"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "initialize"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "initialize"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "update_param"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "symbol": "FEE"
+ },
+ {
+ "u64": 100
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "author"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "sequence"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "284c0039d44629af44654b24c8c9aee1b033da7d16c37cf01135e985b5c79ba8"
+ }
+ }
+ ]
+ },
+ {
+ "bytes": "0606060606060606060606060606060606060606060606060606060606060606"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 257
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "284c0039d44629af44654b24c8c9aee1b033da7d16c37cf01135e985b5c79ba8"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "update_param"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000001"
+ },
+ {
+ "symbol": "register_proof"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "bytes": "0808080808080808080808080808080808080808080808080808080808080808"
+ },
+ {
+ "bytes": "0707070707070707070707070707070707070707070707070707070707070707"
+ },
+ {
+ "u32": 0
+ },
+ {
+ "map": []
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 2
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "string": "caught error from function"
+ }
+ }
+ }
+ },
+ "failed_call": true
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "contract try_call failed"
+ },
+ {
+ "symbol": "register_proof"
+ },
+ {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "bytes": "0808080808080808080808080808080808080808080808080808080808080808"
+ },
+ {
+ "bytes": "0707070707070707070707070707070707070707070707070707070707070707"
+ },
+ {
+ "u32": 0
+ },
+ {
+ "map": []
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/emergency_recovery/tests/non_admin_cannot_request.1.json b/engine-core/test_snapshots/emergency_recovery/tests/non_admin_cannot_request.1.json
index 2fef8f3..5179fe6 100644
--- a/engine-core/test_snapshots/emergency_recovery/tests/non_admin_cannot_request.1.json
+++ b/engine-core/test_snapshots/emergency_recovery/tests/non_admin_cannot_request.1.json
@@ -1,6 +1,6 @@
{
"generators": {
- "address": 8,
+ "address": 6,
"nonce": 0
},
"auth": [
@@ -46,10 +46,10 @@
"val": {
"vec": [
{
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
},
{
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
}
]
}
@@ -83,7 +83,7 @@
[
{
"contract_data": {
- "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
@@ -98,7 +98,7 @@
"data": {
"contract_data": {
"ext": "v0",
- "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
diff --git a/engine-core/test_snapshots/emergency_recovery/tests/same_admin_cannot_double_approve.1.json b/engine-core/test_snapshots/emergency_recovery/tests/same_admin_cannot_double_approve.1.json
index b4ff2f2..e2d0f6e 100644
--- a/engine-core/test_snapshots/emergency_recovery/tests/same_admin_cannot_double_approve.1.json
+++ b/engine-core/test_snapshots/emergency_recovery/tests/same_admin_cannot_double_approve.1.json
@@ -1,6 +1,6 @@
{
"generators": {
- "address": 7,
+ "address": 5,
"nonce": 0
},
"auth": [
@@ -46,10 +46,10 @@
"val": {
"vec": [
{
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
},
{
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
}
]
}
@@ -83,7 +83,7 @@
[
{
"contract_data": {
- "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
@@ -98,7 +98,7 @@
"data": {
"contract_data": {
"ext": "v0",
- "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
diff --git a/engine-core/test_snapshots/emergency_recovery/tests/single_approval_does_not_execute_when_threshold_is_two.1.json b/engine-core/test_snapshots/emergency_recovery/tests/single_approval_does_not_execute_when_threshold_is_two.1.json
index dc2c210..23837cb 100644
--- a/engine-core/test_snapshots/emergency_recovery/tests/single_approval_does_not_execute_when_threshold_is_two.1.json
+++ b/engine-core/test_snapshots/emergency_recovery/tests/single_approval_does_not_execute_when_threshold_is_two.1.json
@@ -1,13 +1,13 @@
{
"generators": {
- "address": 9,
+ "address": 5,
"nonce": 0
},
"auth": [
[],
[
[
- "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM",
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
{
"function": {
"contract_fn": {
@@ -61,13 +61,10 @@
"val": {
"vec": [
{
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
},
{
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
- },
- {
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLZM"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
}
]
}
@@ -90,7 +87,7 @@
"val": {
"vec": [
{
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
}
]
}
@@ -100,7 +97,7 @@
"symbol": "ER_DEST"
},
"val": {
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATYON"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
}
},
{
@@ -116,7 +113,7 @@
"symbol": "ER_TOKEN"
},
"val": {
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARQG5"
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
}
}
]
@@ -132,7 +129,7 @@
[
{
"contract_data": {
- "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
@@ -147,7 +144,7 @@
"data": {
"contract_data": {
"ext": "v0",
- "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
diff --git a/engine-core/test_snapshots/governance/tests/threshold_transition_sets_unlock.1.json b/engine-core/test_snapshots/governance/tests/threshold_transition_sets_unlock.1.json
new file mode 100644
index 0000000..adccf89
--- /dev/null
+++ b/engine-core/test_snapshots/governance/tests/threshold_transition_sets_unlock.1.json
@@ -0,0 +1,420 @@
+{
+ "generators": {
+ "address": 3,
+ "nonce": 0
+ },
+ "auth": [
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "function_name": "",
+ "args": []
+ }
+ },
+ "sub_invocations": []
+ }
+ ],
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ {
+ "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": "MINSTAKE"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "PROPS"
+ },
+ "val": {
+ "map": [
+ {
+ "key": {
+ "u64": 1
+ },
+ "val": {
+ "vec": [
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "action_hash"
+ },
+ "val": {
+ "bytes": "0707070707070707070707070707070707070707070707070707070707070707"
+ }
+ },
+ {
+ "key": {
+ "symbol": "approved_by"
+ },
+ "val": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "id"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "proposer"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "state"
+ },
+ "val": {
+ "u32": 1
+ }
+ }
+ ]
+ },
+ {
+ "u32": 720
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "SIGNERS"
+ },
+ "val": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "THRESH"
+ },
+ "val": {
+ "u32": 2
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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": 770
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1026
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1026
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/governance_tests/tests/test_duplicate_approval_detection.1.json b/engine-core/test_snapshots/governance_tests/tests/test_duplicate_approval_detection.1.json
index 35779dc..7d4df6e 100644
--- a/engine-core/test_snapshots/governance_tests/tests/test_duplicate_approval_detection.1.json
+++ b/engine-core/test_snapshots/governance_tests/tests/test_duplicate_approval_detection.1.json
@@ -1,6 +1,6 @@
{
"generators": {
- "address": 3,
+ "address": 2,
"nonce": 0
},
"auth": [],
@@ -46,72 +46,6 @@
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": {
@@ -140,42 +74,26 @@
"event": {
"ext": "v0",
"contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
- "type_": "contract",
+ "type_": "diagnostic",
"body": {
"v0": {
"topics": [
{
- "symbol": "EVENT"
+ "symbol": "error"
},
{
- "symbol": "LOG"
+ "error": {
+ "contract": 7
+ }
}
],
"data": {
- "map": [
+ "vec": [
{
- "key": {
- "symbol": "flags"
- },
- "val": {
- "u32": 770
- }
+ "string": "failing with contract error"
},
{
- "key": {
- "symbol": "hash"
- },
- "val": {
- "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- {
- "key": {
- "symbol": "value"
- },
- "val": {
- "u64": 1
- }
+ "u32": 7
}
]
}
@@ -197,32 +115,7 @@
},
{
"error": {
- "auth": "existing_value"
- }
- }
- ],
- "data": {
- "string": "frame is already authorized"
- }
- }
- }
- },
- "failed_call": false
- },
- {
- "event": {
- "ext": "v0",
- "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
- "type_": "diagnostic",
- "body": {
- "v0": {
- "topics": [
- {
- "symbol": "error"
- },
- {
- "error": {
- "auth": "existing_value"
+ "contract": 7
}
}
],
diff --git a/engine-core/test_snapshots/governance_tests/tests/test_full_proposal_lifecycle.1.json b/engine-core/test_snapshots/governance_tests/tests/test_full_proposal_lifecycle.1.json
index d971112..164c2f8 100644
--- a/engine-core/test_snapshots/governance_tests/tests/test_full_proposal_lifecycle.1.json
+++ b/engine-core/test_snapshots/governance_tests/tests/test_full_proposal_lifecycle.1.json
@@ -1,12 +1,32 @@
{
"generators": {
- "address": 3,
+ "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,
+ "sequence_number": 721,
"timestamp": 0,
"network_id": "0000000000000000000000000000000000000000000000000000000000000000",
"base_reserve": 0,
@@ -36,7 +56,108 @@
"executable": {
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
- "storage": null
+ "storage": [
+ {
+ "key": {
+ "symbol": "MINSTAKE"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "PROPS"
+ },
+ "val": {
+ "map": [
+ {
+ "key": {
+ "u64": 1
+ },
+ "val": {
+ "vec": [
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "action_hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "approved_by"
+ },
+ "val": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "id"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "proposer"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "state"
+ },
+ "val": {
+ "u32": 2
+ }
+ }
+ ]
+ },
+ {
+ "u32": 720
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "SIGNERS"
+ },
+ "val": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "THRESH"
+ },
+ "val": {
+ "u32": 1
+ }
+ }
+ ]
}
}
}
@@ -79,39 +200,6 @@
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": {
@@ -188,21 +276,44 @@
"event": {
"ext": "v0",
"contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
- "type_": "diagnostic",
+ "type_": "contract",
"body": {
"v0": {
"topics": [
{
- "symbol": "error"
+ "symbol": "EVENT"
},
{
- "error": {
- "auth": "existing_value"
- }
+ "symbol": "LOG"
}
],
"data": {
- "string": "frame is already authorized"
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1026
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
}
}
}
@@ -213,21 +324,44 @@
"event": {
"ext": "v0",
"contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
- "type_": "diagnostic",
+ "type_": "contract",
"body": {
"v0": {
"topics": [
{
- "symbol": "error"
+ "symbol": "EVENT"
},
{
- "error": {
- "auth": "existing_value"
- }
+ "symbol": "LOG"
}
],
"data": {
- "string": "escalating error to panic"
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1282
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
}
}
}
diff --git a/engine-core/test_snapshots/governance_tests/tests/test_proposal_initial_state_pending.1.json b/engine-core/test_snapshots/governance_tests/tests/test_proposal_initial_state_pending.1.json
index d4f71ad..34b9659 100644
--- a/engine-core/test_snapshots/governance_tests/tests/test_proposal_initial_state_pending.1.json
+++ b/engine-core/test_snapshots/governance_tests/tests/test_proposal_initial_state_pending.1.json
@@ -3,7 +3,11 @@
"address": 2,
"nonce": 0
},
- "auth": [],
+ "auth": [
+ [],
+ [],
+ []
+ ],
"ledger": {
"protocol_version": 21,
"sequence_number": 0,
@@ -36,7 +40,104 @@
"executable": {
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
- "storage": null
+ "storage": [
+ {
+ "key": {
+ "symbol": "MINSTAKE"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "PROPS"
+ },
+ "val": {
+ "map": [
+ {
+ "key": {
+ "u64": 1
+ },
+ "val": {
+ "vec": [
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "action_hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "approved_by"
+ },
+ "val": {
+ "vec": []
+ }
+ },
+ {
+ "key": {
+ "symbol": "id"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "proposer"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "state"
+ },
+ "val": {
+ "u32": 0
+ }
+ }
+ ]
+ },
+ {
+ "u32": 0
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "SIGNERS"
+ },
+ "val": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "THRESH"
+ },
+ "val": {
+ "u32": 1
+ }
+ }
+ ]
}
}
}
@@ -46,39 +147,6 @@
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": {
@@ -107,26 +175,42 @@
"event": {
"ext": "v0",
"contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
- "type_": "diagnostic",
+ "type_": "contract",
"body": {
"v0": {
"topics": [
{
- "symbol": "error"
+ "symbol": "EVENT"
},
{
- "error": {
- "auth": "invalid_action"
- }
+ "symbol": "LOG"
}
],
"data": {
- "vec": [
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 770
+ }
+ },
{
- "string": "Unauthorized function call for address"
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
},
{
- "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
}
]
}
@@ -134,31 +218,6 @@
}
},
"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/governance_tests/tests/test_reject_approval_of_executed_proposal.1.json b/engine-core/test_snapshots/governance_tests/tests/test_reject_approval_of_executed_proposal.1.json
index d294760..a8f3ade 100644
--- a/engine-core/test_snapshots/governance_tests/tests/test_reject_approval_of_executed_proposal.1.json
+++ b/engine-core/test_snapshots/governance_tests/tests/test_reject_approval_of_executed_proposal.1.json
@@ -1,9 +1,11 @@
{
"generators": {
- "address": 4,
+ "address": 3,
"nonce": 0
},
"auth": [
+ [],
+ [],
[
[
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
@@ -19,25 +21,11 @@
}
]
],
- [
- [
- "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
- {
- "function": {
- "contract_fn": {
- "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
- "function_name": "",
- "args": []
- }
- },
- "sub_invocations": []
- }
- ]
- ]
+ []
],
"ledger": {
"protocol_version": 21,
- "sequence_number": 0,
+ "sequence_number": 721,
"timestamp": 0,
"network_id": "0000000000000000000000000000000000000000000000000000000000000000",
"base_reserve": 0,
@@ -68,6 +56,17 @@
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"storage": [
+ {
+ "key": {
+ "symbol": "MINSTAKE"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ },
{
"key": {
"symbol": "PROPS"
@@ -203,6 +202,39 @@
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"
+ },
+ 6312720
+ ]
+ ],
[
{
"contract_code": {
@@ -275,6 +307,102 @@
},
"failed_call": false
},
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1026
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1282
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
{
"event": {
"ext": "v0",
@@ -288,12 +416,19 @@
},
{
"error": {
- "auth": "existing_value"
+ "contract": 5
}
}
],
"data": {
- "string": "frame is already authorized"
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 5
+ }
+ ]
}
}
}
@@ -313,7 +448,7 @@
},
{
"error": {
- "auth": "existing_value"
+ "contract": 5
}
}
],
diff --git a/engine-core/test_snapshots/governance_tests/tests/test_reject_approval_on_approved_proposal.1.json b/engine-core/test_snapshots/governance_tests/tests/test_reject_approval_on_approved_proposal.1.json
index bc11da5..f97e1e5 100644
--- a/engine-core/test_snapshots/governance_tests/tests/test_reject_approval_on_approved_proposal.1.json
+++ b/engine-core/test_snapshots/governance_tests/tests/test_reject_approval_on_approved_proposal.1.json
@@ -1,24 +1,11 @@
{
"generators": {
- "address": 4,
+ "address": 3,
"nonce": 0
},
"auth": [
- [
- [
- "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
- {
- "function": {
- "contract_fn": {
- "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
- "function_name": "",
- "args": []
- }
- },
- "sub_invocations": []
- }
- ]
- ],
+ [],
+ [],
[
[
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
@@ -68,6 +55,17 @@
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"storage": [
+ {
+ "key": {
+ "symbol": "MINSTAKE"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ },
{
"key": {
"symbol": "PROPS"
@@ -203,6 +201,39 @@
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": {
@@ -275,6 +306,54 @@
},
"failed_call": false
},
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1026
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
{
"event": {
"ext": "v0",
@@ -288,12 +367,19 @@
},
{
"error": {
- "auth": "existing_value"
+ "contract": 5
}
}
],
"data": {
- "string": "frame is already authorized"
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 5
+ }
+ ]
}
}
}
@@ -313,7 +399,7 @@
},
{
"error": {
- "auth": "existing_value"
+ "contract": 5
}
}
],
diff --git a/engine-core/test_snapshots/governance_tests/tests/test_reject_double_execution.1.json b/engine-core/test_snapshots/governance_tests/tests/test_reject_double_execution.1.json
index 929eecd..8dc4f99 100644
--- a/engine-core/test_snapshots/governance_tests/tests/test_reject_double_execution.1.json
+++ b/engine-core/test_snapshots/governance_tests/tests/test_reject_double_execution.1.json
@@ -1,24 +1,11 @@
{
"generators": {
- "address": 3,
+ "address": 2,
"nonce": 0
},
"auth": [
- [
- [
- "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
- {
- "function": {
- "contract_fn": {
- "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
- "function_name": "",
- "args": []
- }
- },
- "sub_invocations": []
- }
- ]
- ],
+ [],
+ [],
[
[
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
@@ -37,7 +24,7 @@
],
"ledger": {
"protocol_version": 21,
- "sequence_number": 0,
+ "sequence_number": 721,
"timestamp": 0,
"network_id": "0000000000000000000000000000000000000000000000000000000000000000",
"base_reserve": 0,
@@ -68,6 +55,17 @@
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"storage": [
+ {
+ "key": {
+ "symbol": "MINSTAKE"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ },
{
"key": {
"symbol": "PROPS"
@@ -200,39 +198,6 @@
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": {
@@ -305,6 +270,54 @@
},
"failed_call": false
},
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1026
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
{
"event": {
"ext": "v0",
@@ -366,12 +379,19 @@
},
{
"error": {
- "auth": "existing_value"
+ "contract": 5
}
}
],
"data": {
- "string": "frame is already authorized"
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 5
+ }
+ ]
}
}
}
@@ -391,7 +411,7 @@
},
{
"error": {
- "auth": "existing_value"
+ "contract": 5
}
}
],
diff --git a/engine-core/test_snapshots/governance_tests/tests/test_reject_execution_of_pending_proposal.1.json b/engine-core/test_snapshots/governance_tests/tests/test_reject_execution_of_pending_proposal.1.json
index 0448f4f..5460512 100644
--- a/engine-core/test_snapshots/governance_tests/tests/test_reject_execution_of_pending_proposal.1.json
+++ b/engine-core/test_snapshots/governance_tests/tests/test_reject_execution_of_pending_proposal.1.json
@@ -3,7 +3,10 @@
"address": 2,
"nonce": 0
},
- "auth": [],
+ "auth": [
+ [],
+ []
+ ],
"ledger": {
"protocol_version": 21,
"sequence_number": 0,
@@ -36,7 +39,104 @@
"executable": {
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
- "storage": null
+ "storage": [
+ {
+ "key": {
+ "symbol": "MINSTAKE"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "PROPS"
+ },
+ "val": {
+ "map": [
+ {
+ "key": {
+ "u64": 1
+ },
+ "val": {
+ "vec": [
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "action_hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "approved_by"
+ },
+ "val": {
+ "vec": []
+ }
+ },
+ {
+ "key": {
+ "symbol": "id"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "proposer"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "state"
+ },
+ "val": {
+ "u32": 0
+ }
+ }
+ ]
+ },
+ {
+ "u32": 0
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "SIGNERS"
+ },
+ "val": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "THRESH"
+ },
+ "val": {
+ "u32": 1
+ }
+ }
+ ]
}
}
}
@@ -69,5 +169,111 @@
]
]
},
- "events": []
+ "events": [
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 770
+ }
+ },
+ {
+ "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": 5
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 5
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 5
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/governance_tests/tests/test_state_transition_approved_to_executed.1.json b/engine-core/test_snapshots/governance_tests/tests/test_state_transition_approved_to_executed.1.json
index d971112..293e175 100644
--- a/engine-core/test_snapshots/governance_tests/tests/test_state_transition_approved_to_executed.1.json
+++ b/engine-core/test_snapshots/governance_tests/tests/test_state_transition_approved_to_executed.1.json
@@ -1,12 +1,31 @@
{
"generators": {
- "address": 3,
+ "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,
+ "sequence_number": 721,
"timestamp": 0,
"network_id": "0000000000000000000000000000000000000000000000000000000000000000",
"base_reserve": 0,
@@ -36,7 +55,108 @@
"executable": {
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
- "storage": null
+ "storage": [
+ {
+ "key": {
+ "symbol": "MINSTAKE"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "PROPS"
+ },
+ "val": {
+ "map": [
+ {
+ "key": {
+ "u64": 1
+ },
+ "val": {
+ "vec": [
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "action_hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "approved_by"
+ },
+ "val": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "id"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "proposer"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "state"
+ },
+ "val": {
+ "u32": 2
+ }
+ }
+ ]
+ },
+ {
+ "u32": 720
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "SIGNERS"
+ },
+ "val": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "THRESH"
+ },
+ "val": {
+ "u32": 1
+ }
+ }
+ ]
}
}
}
@@ -79,39 +199,6 @@
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": {
@@ -188,21 +275,44 @@
"event": {
"ext": "v0",
"contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
- "type_": "diagnostic",
+ "type_": "contract",
"body": {
"v0": {
"topics": [
{
- "symbol": "error"
+ "symbol": "EVENT"
},
{
- "error": {
- "auth": "existing_value"
- }
+ "symbol": "LOG"
}
],
"data": {
- "string": "frame is already authorized"
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1026
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
}
}
}
@@ -213,21 +323,44 @@
"event": {
"ext": "v0",
"contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
- "type_": "diagnostic",
+ "type_": "contract",
"body": {
"v0": {
"topics": [
{
- "symbol": "error"
+ "symbol": "EVENT"
},
{
- "error": {
- "auth": "existing_value"
- }
+ "symbol": "LOG"
}
],
"data": {
- "string": "escalating error to panic"
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1282
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
}
}
}
diff --git a/engine-core/test_snapshots/governance_tests/tests/test_state_transition_pending_to_approved.1.json b/engine-core/test_snapshots/governance_tests/tests/test_state_transition_pending_to_approved.1.json
index d971112..27b7f0e 100644
--- a/engine-core/test_snapshots/governance_tests/tests/test_state_transition_pending_to_approved.1.json
+++ b/engine-core/test_snapshots/governance_tests/tests/test_state_transition_pending_to_approved.1.json
@@ -1,9 +1,28 @@
{
"generators": {
- "address": 3,
+ "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 +55,108 @@
"executable": {
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
- "storage": null
+ "storage": [
+ {
+ "key": {
+ "symbol": "MINSTAKE"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "PROPS"
+ },
+ "val": {
+ "map": [
+ {
+ "key": {
+ "u64": 1
+ },
+ "val": {
+ "vec": [
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "action_hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "approved_by"
+ },
+ "val": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "id"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "proposer"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "symbol": "state"
+ },
+ "val": {
+ "u32": 1
+ }
+ }
+ ]
+ },
+ {
+ "u32": 720
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "SIGNERS"
+ },
+ "val": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "symbol": "THRESH"
+ },
+ "val": {
+ "u32": 1
+ }
+ }
+ ]
}
}
}
@@ -79,39 +199,6 @@
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": {
@@ -188,46 +275,44 @@
"event": {
"ext": "v0",
"contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
- "type_": "diagnostic",
+ "type_": "contract",
"body": {
"v0": {
"topics": [
{
- "symbol": "error"
+ "symbol": "EVENT"
},
{
- "error": {
- "auth": "existing_value"
- }
+ "symbol": "LOG"
}
],
"data": {
- "string": "frame is already authorized"
- }
- }
- }
- },
- "failed_call": false
- },
- {
- "event": {
- "ext": "v0",
- "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
- "type_": "diagnostic",
- "body": {
- "v0": {
- "topics": [
- {
- "symbol": "error"
- },
- {
- "error": {
- "auth": "existing_value"
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1026
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
}
- }
- ],
- "data": {
- "string": "escalating error to panic"
+ ]
}
}
}
diff --git a/engine-core/test_snapshots/protocol_fee/tests/fee_at_full_bps_is_full_amount.1.json b/engine-core/test_snapshots/protocol_fee/tests/fee_at_full_bps_is_full_amount.1.json
new file mode 100644
index 0000000..caec516
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/fee_at_full_bps_is_full_amount.1.json
@@ -0,0 +1,93 @@
+{
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 10000
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "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": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/fee_calculation_fractional_bps.1.json b/engine-core/test_snapshots/protocol_fee/tests/fee_calculation_fractional_bps.1.json
new file mode 100644
index 0000000..6b2abfc
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/fee_calculation_fractional_bps.1.json
@@ -0,0 +1,93 @@
+{
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 333
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "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": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/fee_calculation_rounds_down.1.json b/engine-core/test_snapshots/protocol_fee/tests/fee_calculation_rounds_down.1.json
new file mode 100644
index 0000000..6b2abfc
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/fee_calculation_rounds_down.1.json
@@ -0,0 +1,93 @@
+{
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 333
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "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": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/fee_calculation_standard.1.json b/engine-core/test_snapshots/protocol_fee/tests/fee_calculation_standard.1.json
new file mode 100644
index 0000000..e9eb5c1
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/fee_calculation_standard.1.json
@@ -0,0 +1,93 @@
+{
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 500
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "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": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/fee_calculation_zero_bps.1.json b/engine-core/test_snapshots/protocol_fee/tests/fee_calculation_zero_bps.1.json
new file mode 100644
index 0000000..cbecf3a
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/fee_calculation_zero_bps.1.json
@@ -0,0 +1,93 @@
+{
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "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": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_circuit_open_panics.1.json b/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_circuit_open_panics.1.json
new file mode 100644
index 0000000..2b8e2c9
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_circuit_open_panics.1.json
@@ -0,0 +1,231 @@
+{
+ "generators": {
+ "address": 6,
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 500
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 801925984706572462
+ }
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4",
+ "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": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1540
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 0
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 1
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_exempt_token_no_fee_deducted.1.json b/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_exempt_token_no_fee_deducted.1.json
new file mode 100644
index 0000000..43bdc44
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_exempt_token_no_fee_deducted.1.json
@@ -0,0 +1,1026 @@
+{
+ "generators": {
+ "address": 6,
+ "nonce": 0
+ },
+ "auth": [
+ [
+ [
+ "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "set_admin",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
+ [],
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "mint",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 1000
+ }
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
+ [],
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "transfer",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 1000
+ }
+ }
+ ]
+ }
+ },
+ "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": [
+ [
+ {
+ "account": {
+ "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "account": {
+ "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ "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": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 801925984706572462
+ }
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 801925984706572462
+ }
+ },
+ "durability": "temporary",
+ "val": "void"
+ }
+ },
+ "ext": "v0"
+ },
+ 6311999
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 5541220902715666415
+ }
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 5541220902715666415
+ }
+ },
+ "durability": "temporary",
+ "val": "void"
+ }
+ },
+ "ext": "v0"
+ },
+ 6311999
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": [
+ {
+ "key": {
+ "symbol": "FEE_BPS"
+ },
+ "val": {
+ "u32": 500
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TOK_EX"
+ },
+ {
+ "address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL"
+ }
+ ]
+ },
+ "val": {
+ "bool": true
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "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": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ }
+ ]
+ },
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ }
+ ]
+ },
+ "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"
+ },
+ 518400
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ }
+ ]
+ },
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ }
+ ]
+ },
+ "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"
+ },
+ 518400
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "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:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ },
+ {
+ "key": {
+ "symbol": "symbol"
+ },
+ "val": {
+ "string": "aaa"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Admin"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "AssetInfo"
+ }
+ ]
+ },
+ "val": {
+ "vec": [
+ {
+ "symbol": "AlphaNum4"
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "asset_code"
+ },
+ "val": {
+ "string": "aaa\\0"
+ }
+ },
+ {
+ "key": {
+ "symbol": "issuer"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000002"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "init_asset"
+ }
+ ],
+ "data": {
+ "bytes": "0000000161616100000000000000000000000000000000000000000000000000000000000000000000000002"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "init_asset"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "set_admin"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "set_admin"
+ },
+ {
+ "address": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "set_admin"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "mint"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 1000
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "mint"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 1000
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "mint"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "transfer"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 1000
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "transfer"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 1000
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "transfer"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 1000
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_full_bps_all_goes_to_recipient.1.json b/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_full_bps_all_goes_to_recipient.1.json
new file mode 100644
index 0000000..1698035
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_full_bps_all_goes_to_recipient.1.json
@@ -0,0 +1,1005 @@
+{
+ "generators": {
+ "address": 6,
+ "nonce": 0
+ },
+ "auth": [
+ [
+ [
+ "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "set_admin",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
+ [],
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "mint",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 200
+ }
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "transfer",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 200
+ }
+ }
+ ]
+ }
+ },
+ "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": [
+ [
+ {
+ "account": {
+ "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "account": {
+ "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ "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": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 801925984706572462
+ }
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 801925984706572462
+ }
+ },
+ "durability": "temporary",
+ "val": "void"
+ }
+ },
+ "ext": "v0"
+ },
+ 6311999
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 5541220902715666415
+ }
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 5541220902715666415
+ }
+ },
+ "durability": "temporary",
+ "val": "void"
+ }
+ },
+ "ext": "v0"
+ },
+ 6311999
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": [
+ {
+ "key": {
+ "symbol": "FEE_BPS"
+ },
+ "val": {
+ "u32": 10000
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "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": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ }
+ ]
+ },
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ }
+ ]
+ },
+ "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": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ }
+ ]
+ },
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ }
+ ]
+ },
+ "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"
+ },
+ 518400
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "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:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ },
+ {
+ "key": {
+ "symbol": "symbol"
+ },
+ "val": {
+ "string": "aaa"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Admin"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "AssetInfo"
+ }
+ ]
+ },
+ "val": {
+ "vec": [
+ {
+ "symbol": "AlphaNum4"
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "asset_code"
+ },
+ "val": {
+ "string": "aaa\\0"
+ }
+ },
+ {
+ "key": {
+ "symbol": "issuer"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000002"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "init_asset"
+ }
+ ],
+ "data": {
+ "bytes": "0000000161616100000000000000000000000000000000000000000000000000000000000000000000000002"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "init_asset"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "set_admin"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "set_admin"
+ },
+ {
+ "address": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "set_admin"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "mint"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 200
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "mint"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 200
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "mint"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "transfer"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 200
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "transfer"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 200
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "transfer"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 3079
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 200
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 200
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_standard_fee_splits_correctly.1.json b/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_standard_fee_splits_correctly.1.json
new file mode 100644
index 0000000..77b0704
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_standard_fee_splits_correctly.1.json
@@ -0,0 +1,1282 @@
+{
+ "generators": {
+ "address": 6,
+ "nonce": 0
+ },
+ "auth": [
+ [
+ [
+ "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "set_admin",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
+ [],
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "mint",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 1000
+ }
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "transfer",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 50
+ }
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ],
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "transfer",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 950
+ }
+ }
+ ]
+ }
+ },
+ "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": [
+ [
+ {
+ "account": {
+ "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "account": {
+ "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ "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": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 801925984706572462
+ }
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 801925984706572462
+ }
+ },
+ "durability": "temporary",
+ "val": "void"
+ }
+ },
+ "ext": "v0"
+ },
+ 6311999
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 5541220902715666415
+ }
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 5541220902715666415
+ }
+ },
+ "durability": "temporary",
+ "val": "void"
+ }
+ },
+ "ext": "v0"
+ },
+ 6311999
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": [
+ {
+ "key": {
+ "symbol": "FEE_BPS"
+ },
+ "val": {
+ "u32": 500
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "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": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ }
+ ]
+ },
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ }
+ ]
+ },
+ "durability": "persistent",
+ "val": {
+ "map": [
+ {
+ "key": {
+ "symbol": "amount"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 50
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "authorized"
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "symbol": "clawback"
+ },
+ "val": {
+ "bool": false
+ }
+ }
+ ]
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 518400
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ }
+ ]
+ },
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ }
+ ]
+ },
+ "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"
+ },
+ 518400
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ }
+ ]
+ },
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ }
+ ]
+ },
+ "durability": "persistent",
+ "val": {
+ "map": [
+ {
+ "key": {
+ "symbol": "amount"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 950
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "authorized"
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "symbol": "clawback"
+ },
+ "val": {
+ "bool": false
+ }
+ }
+ ]
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 518400
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "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:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ },
+ {
+ "key": {
+ "symbol": "symbol"
+ },
+ "val": {
+ "string": "aaa"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Admin"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "AssetInfo"
+ }
+ ]
+ },
+ "val": {
+ "vec": [
+ {
+ "symbol": "AlphaNum4"
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "asset_code"
+ },
+ "val": {
+ "string": "aaa\\0"
+ }
+ },
+ {
+ "key": {
+ "symbol": "issuer"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000002"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "init_asset"
+ }
+ ],
+ "data": {
+ "bytes": "0000000161616100000000000000000000000000000000000000000000000000000000000000000000000002"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "init_asset"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "set_admin"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "set_admin"
+ },
+ {
+ "address": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "set_admin"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "mint"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 1000
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "mint"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 1000
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "mint"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "transfer"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 50
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "transfer"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 50
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "transfer"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "transfer"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 950
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "transfer"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 950
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "transfer"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 3079
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 50
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 950
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 50
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_zero_bps_passes_full_amount.1.json b/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_zero_bps_passes_full_amount.1.json
new file mode 100644
index 0000000..d8689e7
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/fee_on_transfer_zero_bps_passes_full_amount.1.json
@@ -0,0 +1,1005 @@
+{
+ "generators": {
+ "address": 6,
+ "nonce": 0
+ },
+ "auth": [
+ [
+ [
+ "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "set_admin",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
+ [],
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "mint",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 500
+ }
+ }
+ ]
+ }
+ },
+ "sub_invocations": []
+ }
+ ]
+ ],
+ [
+ [
+ "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM",
+ {
+ "function": {
+ "contract_fn": {
+ "contract_address": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "function_name": "transfer",
+ "args": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 500
+ }
+ }
+ ]
+ }
+ },
+ "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": [
+ [
+ {
+ "account": {
+ "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "account": {
+ "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ "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": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 801925984706572462
+ }
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 801925984706572462
+ }
+ },
+ "durability": "temporary",
+ "val": "void"
+ }
+ },
+ "ext": "v0"
+ },
+ 6311999
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 5541220902715666415
+ }
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 5541220902715666415
+ }
+ },
+ "durability": "temporary",
+ "val": "void"
+ }
+ },
+ "ext": "v0"
+ },
+ 6311999
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent",
+ "val": {
+ "contract_instance": {
+ "executable": {
+ "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ },
+ "storage": [
+ {
+ "key": {
+ "symbol": "FEE_BPS"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "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": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ }
+ ]
+ },
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ }
+ ]
+ },
+ "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"
+ },
+ 518400
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ }
+ ]
+ },
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Balance"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ }
+ ]
+ },
+ "durability": "persistent",
+ "val": {
+ "map": [
+ {
+ "key": {
+ "symbol": "amount"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 500
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "authorized"
+ },
+ "val": {
+ "bool": true
+ }
+ },
+ {
+ "key": {
+ "symbol": "clawback"
+ },
+ "val": {
+ "bool": false
+ }
+ }
+ ]
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 518400
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CBEPDNVYXQGWB5YUBXKJWYJA7OXTZW5LFLNO5JRRGE6Z6C5OSUZPCCEL",
+ "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:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ },
+ {
+ "key": {
+ "symbol": "symbol"
+ },
+ "val": {
+ "string": "aaa"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "Admin"
+ }
+ ]
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "AssetInfo"
+ }
+ ]
+ },
+ "val": {
+ "vec": [
+ {
+ "symbol": "AlphaNum4"
+ },
+ {
+ "map": [
+ {
+ "key": {
+ "symbol": "asset_code"
+ },
+ "val": {
+ "string": "aaa\\0"
+ }
+ },
+ {
+ "key": {
+ "symbol": "issuer"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000002"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "init_asset"
+ }
+ ],
+ "data": {
+ "bytes": "0000000161616100000000000000000000000000000000000000000000000000000000000000000000000002"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "init_asset"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "set_admin"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "set_admin"
+ },
+ {
+ "address": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "set_admin"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "mint"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 500
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "mint"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 500
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "mint"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "transfer"
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ },
+ {
+ "i128": {
+ "hi": 0,
+ "lo": 500
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "transfer"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ },
+ {
+ "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWF"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 500
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "transfer"
+ }
+ ],
+ "data": "void"
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 3079
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 0
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 500
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_call"
+ },
+ {
+ "bytes": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "48f1b6b8bc0d60f7140dd49b6120fbaf3cdbab2adaeea631313d9f0bae9532f1",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "fn_return"
+ },
+ {
+ "symbol": "balance"
+ }
+ ],
+ "data": {
+ "i128": {
+ "hi": 0,
+ "lo": 0
+ }
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/get_fee_config_returns_stored_values.1.json b/engine-core/test_snapshots/protocol_fee/tests/get_fee_config_returns_stored_values.1.json
new file mode 100644
index 0000000..2bad0c5
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/get_fee_config_returns_stored_values.1.json
@@ -0,0 +1,93 @@
+{
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 250
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "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": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/init_rejects_bps_over_max.1.json b/engine-core/test_snapshots/protocol_fee/tests/init_rejects_bps_over_max.1.json
new file mode 100644
index 0000000..dc76d95
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/init_rejects_bps_over_max.1.json
@@ -0,0 +1,131 @@
+{
+ "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": 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_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 1
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/multiple_tokens_exempt_independently.1.json b/engine-core/test_snapshots/protocol_fee/tests/multiple_tokens_exempt_independently.1.json
new file mode 100644
index 0000000..fa3fd61
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/multiple_tokens_exempt_independently.1.json
@@ -0,0 +1,108 @@
+{
+ "generators": {
+ "address": 4,
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 500
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TOK_EX"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
+ }
+ ]
+ },
+ "val": {
+ "bool": true
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/rejects_bps_over_max.1.json b/engine-core/test_snapshots/protocol_fee/tests/rejects_bps_over_max.1.json
new file mode 100644
index 0000000..dc76d95
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/rejects_bps_over_max.1.json
@@ -0,0 +1,131 @@
+{
+ "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": 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_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 1
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/set_fee_bps_updates_rate.1.json b/engine-core/test_snapshots/protocol_fee/tests/set_fee_bps_updates_rate.1.json
new file mode 100644
index 0000000..2f58aa4
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/set_fee_bps_updates_rate.1.json
@@ -0,0 +1,93 @@
+{
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 750
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "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": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/set_fee_recipient_updates_address.1.json b/engine-core/test_snapshots/protocol_fee/tests/set_fee_recipient_updates_address.1.json
new file mode 100644
index 0000000..f33c007
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/set_fee_recipient_updates_address.1.json
@@ -0,0 +1,93 @@
+{
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 100
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/token_exempt_cleared.1.json b/engine-core/test_snapshots/protocol_fee/tests/token_exempt_cleared.1.json
new file mode 100644
index 0000000..822f98d
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/token_exempt_cleared.1.json
@@ -0,0 +1,93 @@
+{
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 500
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "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": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/token_exempt_false_by_default.1.json b/engine-core/test_snapshots/protocol_fee/tests/token_exempt_false_by_default.1.json
new file mode 100644
index 0000000..822f98d
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/token_exempt_false_by_default.1.json
@@ -0,0 +1,93 @@
+{
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 500
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "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": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/token_exempt_set_and_check.1.json b/engine-core/test_snapshots/protocol_fee/tests/token_exempt_set_and_check.1.json
new file mode 100644
index 0000000..072c0a3
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/token_exempt_set_and_check.1.json
@@ -0,0 +1,108 @@
+{
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 500
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "val": {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
+ }
+ },
+ {
+ "key": {
+ "vec": [
+ {
+ "symbol": "TOK_EX"
+ },
+ {
+ "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
+ }
+ ]
+ },
+ "val": {
+ "bool": true
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/protocol_fee/tests/zero_amount_no_fee.1.json b/engine-core/test_snapshots/protocol_fee/tests/zero_amount_no_fee.1.json
new file mode 100644
index 0000000..e9eb5c1
--- /dev/null
+++ b/engine-core/test_snapshots/protocol_fee/tests/zero_amount_no_fee.1.json
@@ -0,0 +1,93 @@
+{
+ "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": "FEE_BPS"
+ },
+ "val": {
+ "u32": 500
+ }
+ },
+ {
+ "key": {
+ "symbol": "FEE_RCP"
+ },
+ "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": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/reentrancy_tests/tests/guard_can_be_reentered_after_exit.1.json b/engine-core/test_snapshots/reentrancy_tests/tests/guard_can_be_reentered_after_exit.1.json
new file mode 100644
index 0000000..4a934ef
--- /dev/null
+++ b/engine-core/test_snapshots/reentrancy_tests/tests/guard_can_be_reentered_after_exit.1.json
@@ -0,0 +1,75 @@
+{
+ "generators": {
+ "address": 1,
+ "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": 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": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/reentrancy_tests/tests/guard_panics_when_entered_twice.1.json b/engine-core/test_snapshots/reentrancy_tests/tests/guard_panics_when_entered_twice.1.json
new file mode 100644
index 0000000..2ed3a03
--- /dev/null
+++ b/engine-core/test_snapshots/reentrancy_tests/tests/guard_panics_when_entered_twice.1.json
@@ -0,0 +1,162 @@
+{
+ "generators": {
+ "address": 1,
+ "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": {
+ "symbol": "RE_GUARD"
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "symbol": "RE_GUARD"
+ },
+ "durability": "temporary",
+ "val": {
+ "bool": true
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 15
+ ]
+ ],
+ [
+ {
+ "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_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 100
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 100
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 100
+ }
+ }
+ ],
+ "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
new file mode 100644
index 0000000..00e3b7f
--- /dev/null
+++ b/engine-core/test_snapshots/treasury/tests/latest_snapshot_is_none_when_empty.1.json
@@ -0,0 +1,100 @@
+{
+ "generators": {
+ "address": 1,
+ "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
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ 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 927d25c..9f08344 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
@@ -21,7 +21,14 @@
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": {
- "symbol": "S1"
+ "vec": [
+ {
+ "symbol": "Snapshot"
+ },
+ {
+ "u64": 1
+ }
+ ]
},
"durability": "temporary"
}
@@ -34,7 +41,14 @@
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": {
- "symbol": "S1"
+ "vec": [
+ {
+ "symbol": "Snapshot"
+ },
+ {
+ "u64": 1
+ }
+ ]
},
"durability": "temporary",
"val": {
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 776fbad..2479ffd 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
@@ -21,7 +21,14 @@
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": {
- "symbol": "S1"
+ "vec": [
+ {
+ "symbol": "Snapshot"
+ },
+ {
+ "u64": 1
+ }
+ ]
},
"durability": "temporary"
}
@@ -34,7 +41,14 @@
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": {
- "symbol": "S1"
+ "vec": [
+ {
+ "symbol": "Snapshot"
+ },
+ {
+ "u64": 1
+ }
+ ]
},
"durability": "temporary",
"val": {
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
new file mode 100644
index 0000000..4041909
--- /dev/null
+++ b/engine-core/test_snapshots/treasury_tests/tests/negative_balance_is_rejected.1.json
@@ -0,0 +1,131 @@
+{
+ "generators": {
+ "address": 1,
+ "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": 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_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 2
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "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/recent_snapshots_are_newest_first.1.json b/engine-core/test_snapshots/treasury_tests/tests/recent_snapshots_are_newest_first.1.json
new file mode 100644
index 0000000..20b6bf4
--- /dev/null
+++ b/engine-core/test_snapshots/treasury_tests/tests/recent_snapshots_are_newest_first.1.json
@@ -0,0 +1,584 @@
+{
+ "generators": {
+ "address": 1,
+ "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": {
+ "vec": [
+ {
+ "symbol": "Snapshot"
+ },
+ {
+ "u64": 1
+ }
+ ]
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Snapshot"
+ },
+ {
+ "u64": 1
+ }
+ ]
+ },
+ "durability": "temporary",
+ "val": {
+ "map": [
+ {
+ "key": {
+ "symbol": "account_count"
+ },
+ "val": {
+ "u32": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "context"
+ },
+ "val": {
+ "map": []
+ }
+ },
+ {
+ "key": {
+ "symbol": "id"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "a076236c5280776b29a6c1e3bb11226ed9f1523a850f5c6d29e28ad780348abc"
+ }
+ },
+ {
+ "key": {
+ "symbol": "timestamp_unix"
+ },
+ "val": {
+ "u64": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "total_balance"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 100
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "trigger"
+ },
+ "val": {
+ "u32": 4
+ }
+ }
+ ]
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 120960
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Snapshot"
+ },
+ {
+ "u64": 2
+ }
+ ]
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Snapshot"
+ },
+ {
+ "u64": 2
+ }
+ ]
+ },
+ "durability": "temporary",
+ "val": {
+ "map": [
+ {
+ "key": {
+ "symbol": "account_count"
+ },
+ "val": {
+ "u32": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "context"
+ },
+ "val": {
+ "map": []
+ }
+ },
+ {
+ "key": {
+ "symbol": "id"
+ },
+ "val": {
+ "u64": 2
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "c760bf97d10cf924412e33513007c06425314a06b4e4ccde18008cb7436cd641"
+ }
+ },
+ {
+ "key": {
+ "symbol": "timestamp_unix"
+ },
+ "val": {
+ "u64": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "total_balance"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 101
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "trigger"
+ },
+ "val": {
+ "u32": 4
+ }
+ }
+ ]
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 120960
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Snapshot"
+ },
+ {
+ "u64": 3
+ }
+ ]
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Snapshot"
+ },
+ {
+ "u64": 3
+ }
+ ]
+ },
+ "durability": "temporary",
+ "val": {
+ "map": [
+ {
+ "key": {
+ "symbol": "account_count"
+ },
+ "val": {
+ "u32": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "context"
+ },
+ "val": {
+ "map": []
+ }
+ },
+ {
+ "key": {
+ "symbol": "id"
+ },
+ "val": {
+ "u64": 3
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "b87a2adf90ba811252461d022e0c7bfefb54ebd45b1d62ac39a8bb961f6d1daa"
+ }
+ },
+ {
+ "key": {
+ "symbol": "timestamp_unix"
+ },
+ "val": {
+ "u64": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "total_balance"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 102
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "trigger"
+ },
+ "val": {
+ "u32": 4
+ }
+ }
+ ]
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 120960
+ ]
+ ],
+ [
+ {
+ "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": 3
+ }
+ },
+ {
+ "key": {
+ "symbol": "SNAPL"
+ },
+ "val": {
+ "u64": 3
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 515
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "a076236c5280776b29a6c1e3bb11226ed9f1523a850f5c6d29e28ad780348abc"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 515
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "c760bf97d10cf924412e33513007c06425314a06b4e4ccde18008cb7436cd641"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 2
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 515
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "b87a2adf90ba811252461d022e0c7bfefb54ebd45b1d62ac39a8bb961f6d1daa"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 3
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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
new file mode 100644
index 0000000..9f08344
--- /dev/null
+++ b/engine-core/test_snapshots/treasury_tests/tests/records_and_retrieves_snapshot.1.json
@@ -0,0 +1,262 @@
+{
+ "generators": {
+ "address": 1,
+ "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": {
+ "vec": [
+ {
+ "symbol": "Snapshot"
+ },
+ {
+ "u64": 1
+ }
+ ]
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "vec": [
+ {
+ "symbol": "Snapshot"
+ },
+ {
+ "u64": 1
+ }
+ ]
+ },
+ "durability": "temporary",
+ "val": {
+ "map": [
+ {
+ "key": {
+ "symbol": "account_count"
+ },
+ "val": {
+ "u32": 5
+ }
+ },
+ {
+ "key": {
+ "symbol": "context"
+ },
+ "val": {
+ "map": []
+ }
+ },
+ {
+ "key": {
+ "symbol": "id"
+ },
+ "val": {
+ "u64": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "ledger"
+ },
+ "val": {
+ "u32": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "state_hash"
+ },
+ "val": {
+ "bytes": "3f669395051abd97652a9c947139d6d477c996972caa38158decad5a49c70efb"
+ }
+ },
+ {
+ "key": {
+ "symbol": "timestamp_unix"
+ },
+ "val": {
+ "u64": 0
+ }
+ },
+ {
+ "key": {
+ "symbol": "total_balance"
+ },
+ "val": {
+ "i128": {
+ "hi": 0,
+ "lo": 1000
+ }
+ }
+ },
+ {
+ "key": {
+ "symbol": "trigger"
+ },
+ "val": {
+ "u32": 0
+ }
+ }
+ ]
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 120960
+ ]
+ ],
+ [
+ {
+ "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": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "SNAPL"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "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": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 515
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "3f669395051abd97652a9c947139d6d477c996972caa38158decad5a49c70efb"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 1
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/upgrade/tests/upgrade_fails_when_hash_was_not_approved.1.json b/engine-core/test_snapshots/upgrade/tests/upgrade_fails_when_hash_was_not_approved.1.json
new file mode 100644
index 0000000..2493a08
--- /dev/null
+++ b/engine-core/test_snapshots/upgrade/tests/upgrade_fails_when_hash_was_not_approved.1.json
@@ -0,0 +1,341 @@
+{
+ "generators": {
+ "address": 3,
+ "nonce": 0
+ },
+ "auth": [],
+ "ledger": {
+ "protocol_version": 21,
+ "sequence_number": 721,
+ "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_nonce": {
+ "nonce": 801925984706572462
+ }
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "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": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "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": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 770
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 7
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1026
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 7
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1026
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 7
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 1
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/upgrade/tests/upgrade_fails_without_quorum.1.json b/engine-core/test_snapshots/upgrade/tests/upgrade_fails_without_quorum.1.json
new file mode 100644
index 0000000..1c1bde7
--- /dev/null
+++ b/engine-core/test_snapshots/upgrade/tests/upgrade_fails_without_quorum.1.json
@@ -0,0 +1,260 @@
+{
+ "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_nonce": {
+ "nonce": 801925984706572462
+ }
+ },
+ "durability": "temporary"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
+ "key": {
+ "ledger_key_nonce": {
+ "nonce": 801925984706572462
+ }
+ },
+ "durability": "temporary",
+ "val": "void"
+ }
+ },
+ "ext": "v0"
+ },
+ 6311999
+ ]
+ ],
+ [
+ {
+ "contract_data": {
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "key": "ledger_key_contract_instance",
+ "durability": "persistent"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_data": {
+ "ext": "v0",
+ "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M",
+ "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": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 770
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 7
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "contract",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "EVENT"
+ },
+ {
+ "symbol": "LOG"
+ }
+ ],
+ "data": {
+ "map": [
+ {
+ "key": {
+ "symbol": "flags"
+ },
+ "val": {
+ "u32": 1026
+ }
+ },
+ {
+ "key": {
+ "symbol": "hash"
+ },
+ "val": {
+ "bytes": "0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "key": {
+ "symbol": "value"
+ },
+ "val": {
+ "u64": 7
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 2
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000003",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/version/tests/init_version_rejects_double_init.1.json b/engine-core/test_snapshots/version/tests/init_version_rejects_double_init.1.json
new file mode 100644
index 0000000..51cedb4
--- /dev/null
+++ b/engine-core/test_snapshots/version/tests/init_version_rejects_double_init.1.json
@@ -0,0 +1,131 @@
+{
+ "generators": {
+ "address": 1,
+ "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": 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_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 1
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": "0000000000000000000000000000000000000000000000000000000000000001",
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 1
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/version/tests/init_version_stores_correctly.1.json b/engine-core/test_snapshots/version/tests/init_version_stores_correctly.1.json
new file mode 100644
index 0000000..24f59f5
--- /dev/null
+++ b/engine-core/test_snapshots/version/tests/init_version_stores_correctly.1.json
@@ -0,0 +1,92 @@
+{
+ "generators": {
+ "address": 1,
+ "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": "VERSION"
+ },
+ "val": {
+ "u32": 1
+ }
+ },
+ {
+ "key": {
+ "symbol": "VER_INIT"
+ },
+ "val": {
+ "bool": true
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/version/tests/require_compatible_rejects_mismatch.1.json b/engine-core/test_snapshots/version/tests/require_compatible_rejects_mismatch.1.json
new file mode 100644
index 0000000..5984b1a
--- /dev/null
+++ b/engine-core/test_snapshots/version/tests/require_compatible_rejects_mismatch.1.json
@@ -0,0 +1,77 @@
+{
+ "generators": {
+ "address": 0,
+ "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": []
+ },
+ "events": [
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 2
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 2
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/version/tests/set_contract_version_works.1.json b/engine-core/test_snapshots/version/tests/set_contract_version_works.1.json
new file mode 100644
index 0000000..f7e6cec
--- /dev/null
+++ b/engine-core/test_snapshots/version/tests/set_contract_version_works.1.json
@@ -0,0 +1,92 @@
+{
+ "generators": {
+ "address": 1,
+ "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": "VERSION"
+ },
+ "val": {
+ "u32": 2
+ }
+ },
+ {
+ "key": {
+ "symbol": "VER_INIT"
+ },
+ "val": {
+ "bool": true
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ],
+ [
+ {
+ "contract_code": {
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ }
+ },
+ [
+ {
+ "last_modified_ledger_seq": 0,
+ "data": {
+ "contract_code": {
+ "ext": "v0",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "code": ""
+ }
+ },
+ "ext": "v0"
+ },
+ 4095
+ ]
+ ]
+ ]
+ },
+ "events": []
+}
\ No newline at end of file
diff --git a/engine-core/test_snapshots/version/tests/upgrade_check_rejects_downgrade.1.json b/engine-core/test_snapshots/version/tests/upgrade_check_rejects_downgrade.1.json
new file mode 100644
index 0000000..8375b89
--- /dev/null
+++ b/engine-core/test_snapshots/version/tests/upgrade_check_rejects_downgrade.1.json
@@ -0,0 +1,77 @@
+{
+ "generators": {
+ "address": 0,
+ "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": []
+ },
+ "events": [
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 3
+ }
+ }
+ ],
+ "data": {
+ "vec": [
+ {
+ "string": "failing with contract error"
+ },
+ {
+ "u32": 3
+ }
+ ]
+ }
+ }
+ }
+ },
+ "failed_call": false
+ },
+ {
+ "event": {
+ "ext": "v0",
+ "contract_id": null,
+ "type_": "diagnostic",
+ "body": {
+ "v0": {
+ "topics": [
+ {
+ "symbol": "error"
+ },
+ {
+ "error": {
+ "contract": 3
+ }
+ }
+ ],
+ "data": {
+ "string": "escalating error to panic"
+ }
+ }
+ }
+ },
+ "failed_call": false
+ }
+ ]
+}
\ No newline at end of file