diff --git a/contracts/escrow/src/lib.rs b/contracts/escrow/src/lib.rs index 7c1eceb..e1c3baa 100644 --- a/contracts/escrow/src/lib.rs +++ b/contracts/escrow/src/lib.rs @@ -1,11 +1,13 @@ #![no_std] use shared::{ - constants::{MIN_VALIDATORS, RESUME_TIME_DELAY, UPGRADE_TIME_LOCK_SECS}, + constants::{ + ESCROW_INITIALIZED, MAX_BATCH_SIZE, MILESTONE_APPROVAL_THRESHOLD, MILESTONE_APPROVED, + MILESTONE_CREATED, MILESTONE_REJECTED, MILESTONE_SUBMITTED, MIN_VALIDATORS, + }, errors::Error, events::*, - types::{Amount, EscrowInfo, Hash, Milestone, MilestoneStatus, PauseState, PendingUpgrade}, - MAX_APPROVAL_THRESHOLD, MIN_APPROVAL_THRESHOLD, + types::{Amount, BatchResult, EscrowInfo, Hash, Milestone, MilestoneStatus}, }; use soroban_sdk::{contract, contractimpl, token::TokenClient, Address, BytesN, Env, Vec}; @@ -305,117 +307,230 @@ impl EscrowContract { Ok(()) } - pub fn pause(env: Env, admin: Address) -> Result<(), Error> { - let stored_admin = get_admin(&env)?; - if stored_admin != admin { - return Err(Error::Unauthorized); - } - admin.require_auth(); - - let now = env.ledger().timestamp(); - let state = PauseState { - paused: true, - paused_at: now, - resume_not_before: now + RESUME_TIME_DELAY, - }; + // ==================== Batch Operations ==================== - set_pause_state(&env, &state); - env.events().publish((CONTRACT_PAUSED,), (admin, now)); - - Ok(()) - } - - pub fn resume(env: Env, admin: Address) -> Result<(), Error> { - let stored_admin = get_admin(&env)?; - if stored_admin != admin { - return Err(Error::Unauthorized); + /// Create multiple milestones for a project in a single call + /// + /// # Arguments + /// * `project_id` - Project identifier + /// * `milestones` - Vec of (description_hash, amount) tuples + pub fn batch_create_milestones( + env: Env, + project_id: u64, + milestones: Vec<(Hash, Amount)>, + ) -> Result { + let count = milestones.len() as u32; + if count == 0 { + return Err(Error::BatchEmpty); } - admin.require_auth(); - - let state = get_pause_state(&env); - - let now = env.ledger().timestamp(); - if now < state.resume_not_before { - return Err(Error::ResumeTooEarly); + if count > MAX_BATCH_SIZE { + return Err(Error::BatchLimitExceeded); } - let new_state = PauseState { - paused: false, - paused_at: state.paused_at, - resume_not_before: state.resume_not_before, - }; - - set_pause_state(&env, &new_state); - env.events().publish((CONTRACT_RESUMED,), (admin, now)); + // Get escrow and authenticate creator once + let escrow = get_escrow(&env, project_id)?; + escrow.creator.require_auth(); - Ok(()) - } + let mut successful: u32 = 0; + let mut failed: u32 = 0; + let mut milestone_id = get_milestone_counter(&env, project_id)?; + let mut running_total = get_total_milestone_amount(&env, project_id)?; + + for i in 0..milestones.len() { + let (description_hash, amount) = milestones.get(i).unwrap(); + + // Validate amount + if amount <= 0 { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), (project_id, i as u32)); + continue; + } + + // Validate total doesn't exceed escrow balance + let new_total = match running_total.checked_add(amount) { + Some(t) => t, + None => { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), (project_id, i as u32)); + continue; + } + }; + + if new_total > escrow.total_deposited { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), (project_id, i as u32)); + continue; + } + + // Create milestone + let empty_hash = BytesN::from_array(&env, &[0u8; 32]); + let milestone = Milestone { + id: milestone_id, + project_id, + description_hash: description_hash.clone(), + amount, + status: MilestoneStatus::Pending, + proof_hash: empty_hash, + approval_count: 0, + rejection_count: 0, + created_at: env.ledger().timestamp(), + }; - pub fn get_is_paused(env: Env) -> bool { - is_paused(&env) - } + set_milestone(&env, project_id, milestone_id, &milestone); + running_total = new_total; + milestone_id += 1; + successful += 1; - pub fn schedule_upgrade( - env: Env, - admin: Address, - new_wasm_hash: BytesN<32>, - ) -> Result<(), Error> { - let stored_admin = get_admin(&env)?; - if stored_admin != admin { - return Err(Error::Unauthorized); + env.events().publish( + (MILESTONE_CREATED,), + (project_id, milestone.id, amount, description_hash), + ); } - admin.require_auth(); - let now = env.ledger().timestamp(); - let pending = PendingUpgrade { - wasm_hash: new_wasm_hash.clone(), - execute_not_before: now + UPGRADE_TIME_LOCK_SECS, - }; - set_pending_upgrade(&env, &pending); + + // Update the milestone counter once + set_milestone_counter(&env, project_id, milestone_id); + env.events().publish( - (UPGRADE_SCHEDULED,), - (admin, new_wasm_hash, pending.execute_not_before), + (BATCH_COMPLETED,), + (project_id, successful, failed), ); - Ok(()) + + Ok(BatchResult { + total: count, + successful, + failed, + }) } - pub fn execute_upgrade(env: Env, admin: Address) -> Result<(), Error> { - let stored_admin = get_admin(&env)?; - if stored_admin != admin { - return Err(Error::Unauthorized); - } - admin.require_auth(); - if !is_paused(&env) { - return Err(Error::UpgradeRequiresPause); + /// Vote on multiple milestones in a single call + /// + /// # Arguments + /// * `project_id` - Project identifier + /// * `votes` - Vec of (milestone_id, approve) tuples + /// * `voter` - Address of the voter + pub fn batch_vote_milestones( + env: Env, + project_id: u64, + votes: Vec<(u64, bool)>, + voter: Address, + ) -> Result { + let count = votes.len() as u32; + if count == 0 { + return Err(Error::BatchEmpty); } - let pending = get_pending_upgrade(&env).ok_or(Error::UpgradeNotScheduled)?; - let now = env.ledger().timestamp(); - if now < pending.execute_not_before { - return Err(Error::UpgradeTooEarly); + if count > MAX_BATCH_SIZE { + return Err(Error::BatchLimitExceeded); } - env.deployer() - .update_current_contract_wasm(pending.wasm_hash.clone()); - clear_pending_upgrade(&env); - env.events() - .publish((UPGRADE_EXECUTED,), (admin, pending.wasm_hash)); - Ok(()) - } - pub fn cancel_upgrade(env: Env, admin: Address) -> Result<(), Error> { - let stored_admin = get_admin(&env)?; - if stored_admin != admin { - return Err(Error::Unauthorized); + // Authenticate voter once + voter.require_auth(); + + // Get escrow and verify voter is a validator + let mut escrow = get_escrow(&env, project_id)?; + if !escrow.validators.iter().any(|v| v == voter) { + return Err(Error::NotAValidator); } - admin.require_auth(); - if !has_pending_upgrade(&env) { - return Err(Error::UpgradeNotScheduled); + + let mut successful: u32 = 0; + let mut failed: u32 = 0; + + for i in 0..votes.len() { + let (milestone_id, approve) = votes.get(i).unwrap(); + + // Get milestone - skip if not found + let mut milestone = match get_milestone(&env, project_id, milestone_id) { + Ok(m) => m, + Err(_) => { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), (project_id, milestone_id)); + continue; + } + }; + + // Validate milestone status + if milestone.status != MilestoneStatus::Submitted { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), (project_id, milestone_id)); + continue; + } + + // Check if already voted + if has_validator_voted(&env, project_id, milestone_id, &voter).unwrap_or(false) { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), (project_id, milestone_id)); + continue; + } + + // Update vote counts + if approve { + milestone.approval_count = milestone + .approval_count + .checked_add(1) + .unwrap_or(milestone.approval_count); + } else { + milestone.rejection_count = milestone + .rejection_count + .checked_add(1) + .unwrap_or(milestone.rejection_count); + } + + // Record vote + let _ = set_validator_vote(&env, project_id, milestone_id, &voter); + + // Check for milestone finalization + let required_approvals = + (escrow.validators.len() as u32 * MILESTONE_APPROVAL_THRESHOLD) / 10000; + + if milestone.approval_count as u32 >= required_approvals { + milestone.status = MilestoneStatus::Approved; + + // Release funds + if release_milestone_funds(&env, &mut escrow, &milestone).is_ok() { + let token_client = TokenClient::new(&env, &escrow.token); + token_client.transfer( + &env.current_contract_address(), + &escrow.creator, + &milestone.amount, + ); + set_escrow(&env, project_id, &escrow); + + env.events().publish( + (MILESTONE_APPROVED,), + (project_id, milestone_id, milestone.approval_count), + ); + env.events().publish( + (FUNDS_RELEASED,), + (project_id, milestone_id, milestone.amount), + ); + } + } else if milestone.rejection_count as u32 + > escrow.validators.len() as u32 - required_approvals + { + milestone.status = MilestoneStatus::Rejected; + env.events().publish( + (MILESTONE_REJECTED,), + (project_id, milestone_id, milestone.rejection_count), + ); + } + + set_milestone(&env, project_id, milestone_id, &milestone); + successful += 1; } - clear_pending_upgrade(&env); - env.events().publish((UPGRADE_CANCELLED,), admin); - Ok(()) - } - pub fn get_pending_upgrade(env: Env) -> Option { - storage::get_pending_upgrade(&env) + env.events() + .publish((BATCH_COMPLETED,), (project_id, successful, failed)); + + Ok(BatchResult { + total: count, + successful, + failed, + }) } } diff --git a/contracts/governance/src/lib.rs b/contracts/governance/src/lib.rs index fdd60cb..86c15cd 100644 --- a/contracts/governance/src/lib.rs +++ b/contracts/governance/src/lib.rs @@ -1,12 +1,12 @@ #![no_std] use shared::{ - constants::GOVERNANCE_QUORUM, + constants::{GOVERNANCE_QUORUM, MAX_BATCH_SIZE}, errors::Error, - events::{PROPOSAL_CREATED, PROPOSAL_EXECUTED, VOTE_CAST}, - types::{Amount, Proposal}, + events::{BATCH_COMPLETED, BATCH_ITEM_FAILED, PROPOSAL_CREATED, PROPOSAL_EXECUTED, VOTE_CAST}, + types::{BatchResult, Proposal}, }; -use soroban_sdk::{contract, contractimpl, contracttype, token, Address, Bytes, Env, Vec}; +use soroban_sdk::{contract, contractimpl, contracttype, Address, Bytes, Env, Vec}; #[contracttype] #[derive(Clone)] @@ -356,23 +356,100 @@ impl GovernanceContract { .unwrap_or(0) } - pub fn get_stake(env: Env, voter: Address) -> Amount { - env.storage() - .instance() - .get(&DataKey::Stake(voter)) - .unwrap_or(0) - } + // ==================== Batch Operations ==================== - pub fn get_total_stake(env: Env) -> Amount { - env.storage() - .instance() - .get(&DataKey::TotalStake) - .unwrap_or(0) - } + /// Cast votes on multiple proposals in a single call + /// + /// # Arguments + /// * `votes` - Vec of (proposal_id, support) tuples + /// * `voter` - Address of the voter + pub fn batch_vote( + env: Env, + votes: Vec<(u64, bool)>, + voter: Address, + ) -> Result { + let count = votes.len() as u32; + if count == 0 { + return Err(Error::BatchEmpty); + } + if count > MAX_BATCH_SIZE { + return Err(Error::BatchLimitExceeded); + } - pub fn get_proposal_timelock(env: Env, proposal_id: u64) -> Option { - env.storage() - .instance() - .get(&DataKey::ProposalTimelock(proposal_id)) + // Authenticate voter once + voter.require_auth(); + + let current_time = env.ledger().timestamp(); + let mut successful: u32 = 0; + let mut failed: u32 = 0; + + for i in 0..votes.len() { + let (proposal_id, support) = votes.get(i).unwrap(); + + // Get proposal - skip if not found + let mut proposal: Proposal = match env + .storage() + .instance() + .get(&DataKey::Proposal(proposal_id)) + { + Some(p) => p, + None => { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), proposal_id); + continue; + } + }; + + // Skip if already executed + if proposal.executed { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), proposal_id); + continue; + } + + // Skip if outside voting window + if current_time < proposal.start_time || current_time > proposal.end_time { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), proposal_id); + continue; + } + + // Skip if already voted + let vote_key = DataKey::HasVoted(proposal_id, voter.clone()); + if env.storage().instance().has(&vote_key) { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), proposal_id); + continue; + } + + // Cast vote + if support { + proposal.yes_votes += 1; + } else { + proposal.no_votes += 1; + } + + env.storage() + .instance() + .set(&DataKey::Proposal(proposal_id), &proposal); + env.storage().instance().set(&vote_key, &true); + + env.events() + .publish((VOTE_CAST,), (proposal_id, voter.clone(), support)); + successful += 1; + } + + env.events() + .publish((BATCH_COMPLETED,), (successful, failed)); + + Ok(BatchResult { + total: count, + successful, + failed, + }) } } diff --git a/contracts/governance/src/tests.rs b/contracts/governance/src/tests.rs index efb9359..5c559b5 100644 --- a/contracts/governance/src/tests.rs +++ b/contracts/governance/src/tests.rs @@ -515,3 +515,86 @@ fn test_token_weighted_voting_and_quorum_with_timelock() { let timelock = client.get_proposal_timelock(&proposal_id).unwrap(); assert!(timelock > current_time); } + +// ==================== Batch Operation Tests ==================== + +#[test] +fn test_batch_vote_success() { + let (env, client, admin, creator, _) = setup_test_env(); + initialize_contract(&client, &admin, 100); + + // Create 3 proposals + let p1 = create_test_proposal(&env, &client, &creator, 0, 1000); + let p2 = create_test_proposal(&env, &client, &creator, 0, 1000); + let p3 = create_test_proposal(&env, &client, &creator, 0, 1000); + + let voter = Address::generate(&env); + env.mock_all_auths(); + + // Batch vote on all 3 + let mut votes = Vec::new(&env); + votes.push_back((p1, true)); + votes.push_back((p2, false)); + votes.push_back((p3, true)); + + let result = client.batch_vote(&votes, &voter); + assert_eq!(result.total, 3); + assert_eq!(result.successful, 3); + assert_eq!(result.failed, 0); + + // Verify votes were recorded + assert!(client.has_voted(&p1, &voter)); + assert!(client.has_voted(&p2, &voter)); + assert!(client.has_voted(&p3, &voter)); + + let prop1 = client.get_proposal(&p1); + assert_eq!(prop1.yes_votes, 1); + let prop2 = client.get_proposal(&p2); + assert_eq!(prop2.no_votes, 1); +} + +#[test] +fn test_batch_vote_partial_failure() { + let (env, client, admin, creator, _) = setup_test_env(); + initialize_contract(&client, &admin, 100); + + // Create 2 proposals + let p1 = create_test_proposal(&env, &client, &creator, 0, 1000); + let p2 = create_test_proposal(&env, &client, &creator, 0, 1000); + + let voter = Address::generate(&env); + env.mock_all_auths(); + + // Vote on p1 individually first + client.vote(&p1, &voter, &true); + + // Batch vote: p1 should fail (already voted), p2 should succeed, 999 should fail (not found) + let mut votes = Vec::new(&env); + votes.push_back((p1, true)); // already voted + votes.push_back((p2, false)); // should succeed + votes.push_back((999, true)); // doesn't exist + + let result = client.batch_vote(&votes, &voter); + assert_eq!(result.total, 3); + assert_eq!(result.successful, 1); + assert_eq!(result.failed, 2); + + // p2 vote should have been recorded + assert!(client.has_voted(&p2, &voter)); + let prop2 = client.get_proposal(&p2); + assert_eq!(prop2.no_votes, 1); +} + +#[test] +fn test_batch_vote_empty() { + let (env, client, admin, _, _) = setup_test_env(); + initialize_contract(&client, &admin, 100); + + let voter = Address::generate(&env); + env.mock_all_auths(); + + let votes: Vec<(u64, bool)> = Vec::new(&env); + let result = client.try_batch_vote(&votes, &voter); + assert!(result.is_err()); +} + diff --git a/contracts/governance/test_snapshots/tests/test_batch_vote_empty.1.json b/contracts/governance/test_snapshots/tests/test_batch_vote_empty.1.json new file mode 100644 index 0000000..ec6aabb --- /dev/null +++ b/contracts/governance/test_snapshots/tests/test_batch_vote_empty.1.json @@ -0,0 +1,323 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "initialize", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 100 + } + ] + } + }, + "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": { + "vec": [ + { + "symbol": "TotalVoters" + } + ] + }, + "val": { + "u32": 100 + } + } + ] + } + } + } + }, + "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": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 100 + } + ] + } + } + } + }, + "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": "batch_vote" + } + ], + "data": { + "vec": [ + { + "vec": [] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "batch_vote" + } + ], + "data": { + "error": { + "contract": 801 + } + } + } + } + }, + "failed_call": true + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "contract": 801 + } + } + ], + "data": { + "string": "escalating Ok(ScErrorType::Contract) frame-exit to Err" + } + } + } + }, + "failed_call": true + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "error" + }, + { + "error": { + "contract": 801 + } + } + ], + "data": { + "vec": [ + { + "string": "contract try_call failed" + }, + { + "symbol": "batch_vote" + }, + { + "vec": [ + { + "vec": [] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/contracts/governance/test_snapshots/tests/test_batch_vote_partial_failure.1.json b/contracts/governance/test_snapshots/tests/test_batch_vote_partial_failure.1.json new file mode 100644 index 0000000..2c1e47b --- /dev/null +++ b/contracts/governance/test_snapshots/tests/test_batch_vote_partial_failure.1.json @@ -0,0 +1,1323 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "initialize", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 100 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_proposal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + }, + { + "u64": 0 + }, + { + "u64": 1000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_proposal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + }, + { + "u64": 0 + }, + { + "u64": 1000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "vote", + "args": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "bool": true + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "batch_vote", + "args": [ + { + "vec": [ + { + "vec": [ + { + "u64": 0 + }, + { + "bool": true + } + ] + }, + { + "vec": [ + { + "u64": 1 + }, + { + "bool": false + } + ] + }, + { + "vec": [ + { + "u64": 999 + }, + { + "bool": true + } + ] + } + ] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + }, + "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": { + "vec": [ + { + "symbol": "HasVoted" + }, + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "val": { + "bool": true + } + }, + { + "key": { + "vec": [ + { + "symbol": "HasVoted" + }, + { + "u64": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "val": { + "bool": true + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextProposalId" + } + ] + }, + "val": { + "u64": 2 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Proposal" + }, + { + "u64": 0 + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "creator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "end_time" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "no_votes" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "payload_ref" + }, + "val": { + "bytes": "697066733a2f2f516d54657374313233" + } + }, + { + "key": { + "symbol": "start_time" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "yes_votes" + }, + "val": { + "u32": 1 + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Proposal" + }, + { + "u64": 1 + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "creator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "end_time" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "no_votes" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "payload_ref" + }, + "val": { + "bytes": "697066733a2f2f516d54657374313233" + } + }, + { + "key": { + "symbol": "start_time" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "yes_votes" + }, + "val": { + "u32": 0 + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "TotalVoters" + } + ] + }, + "val": { + "u32": 100 + } + } + ] + } + } + } + }, + "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": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "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_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": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 100 + } + ] + } + } + } + }, + "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": "create_proposal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + }, + { + "u64": 0 + }, + { + "u64": 1000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "proposal" + } + ], + "data": { + "vec": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_proposal" + } + ], + "data": { + "u64": 0 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_proposal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + }, + { + "u64": 0 + }, + { + "u64": 1000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "proposal" + } + ], + "data": { + "vec": [ + { + "u64": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_proposal" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "vote" + } + ], + "data": { + "vec": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "bool": true + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "vote" + } + ], + "data": { + "vec": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "bool": true + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "vote" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "batch_vote" + } + ], + "data": { + "vec": [ + { + "vec": [ + { + "vec": [ + { + "u64": 0 + }, + { + "bool": true + } + ] + }, + { + "vec": [ + { + "u64": 1 + }, + { + "bool": false + } + ] + }, + { + "vec": [ + { + "u64": 999 + }, + { + "bool": true + } + ] + } + ] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "batch_fl" + } + ], + "data": { + "u64": 0 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "vote" + } + ], + "data": { + "vec": [ + { + "u64": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "bool": false + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "batch_fl" + } + ], + "data": { + "u64": 999 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "batch_ok" + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "u32": 2 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "batch_vote" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "failed" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "successful" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "total" + }, + "val": { + "u32": 3 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "has_voted" + } + ], + "data": { + "vec": [ + { + "u64": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "has_voted" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_proposal" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_proposal" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "creator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "end_time" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "no_votes" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "payload_ref" + }, + "val": { + "bytes": "697066733a2f2f516d54657374313233" + } + }, + { + "key": { + "symbol": "start_time" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "yes_votes" + }, + "val": { + "u32": 0 + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/contracts/governance/test_snapshots/tests/test_batch_vote_success.1.json b/contracts/governance/test_snapshots/tests/test_batch_vote_success.1.json new file mode 100644 index 0000000..62f169e --- /dev/null +++ b/contracts/governance/test_snapshots/tests/test_batch_vote_success.1.json @@ -0,0 +1,1678 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "initialize", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 100 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_proposal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + }, + { + "u64": 0 + }, + { + "u64": 1000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_proposal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + }, + { + "u64": 0 + }, + { + "u64": 1000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "create_proposal", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + }, + { + "u64": 0 + }, + { + "u64": 1000 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "function_name": "batch_vote", + "args": [ + { + "vec": [ + { + "vec": [ + { + "u64": 0 + }, + { + "bool": true + } + ] + }, + { + "vec": [ + { + "u64": 1 + }, + { + "bool": false + } + ] + }, + { + "vec": [ + { + "u64": 2 + }, + { + "bool": true + } + ] + } + ] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + }, + "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": { + "vec": [ + { + "symbol": "HasVoted" + }, + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "val": { + "bool": true + } + }, + { + "key": { + "vec": [ + { + "symbol": "HasVoted" + }, + { + "u64": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "val": { + "bool": true + } + }, + { + "key": { + "vec": [ + { + "symbol": "HasVoted" + }, + { + "u64": 2 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "val": { + "bool": true + } + }, + { + "key": { + "vec": [ + { + "symbol": "NextProposalId" + } + ] + }, + "val": { + "u64": 3 + } + }, + { + "key": { + "vec": [ + { + "symbol": "Proposal" + }, + { + "u64": 0 + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "creator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "end_time" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "no_votes" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "payload_ref" + }, + "val": { + "bytes": "697066733a2f2f516d54657374313233" + } + }, + { + "key": { + "symbol": "start_time" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "yes_votes" + }, + "val": { + "u32": 1 + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Proposal" + }, + { + "u64": 1 + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "creator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "end_time" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "no_votes" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "payload_ref" + }, + "val": { + "bytes": "697066733a2f2f516d54657374313233" + } + }, + { + "key": { + "symbol": "start_time" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "yes_votes" + }, + "val": { + "u32": 0 + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "Proposal" + }, + { + "u64": 2 + } + ] + }, + "val": { + "map": [ + { + "key": { + "symbol": "creator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "end_time" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 2 + } + }, + { + "key": { + "symbol": "no_votes" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "payload_ref" + }, + "val": { + "bytes": "697066733a2f2f516d54657374313233" + } + }, + { + "key": { + "symbol": "start_time" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "yes_votes" + }, + "val": { + "u32": 1 + } + } + ] + } + }, + { + "key": { + "vec": [ + { + "symbol": "TotalVoters" + } + ] + }, + "val": { + "u32": 100 + } + } + ] + } + } + } + }, + "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": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 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_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "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": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 100 + } + ] + } + } + } + }, + "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": "create_proposal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + }, + { + "u64": 0 + }, + { + "u64": 1000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "proposal" + } + ], + "data": { + "vec": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_proposal" + } + ], + "data": { + "u64": 0 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_proposal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + }, + { + "u64": 0 + }, + { + "u64": 1000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "proposal" + } + ], + "data": { + "vec": [ + { + "u64": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_proposal" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "create_proposal" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + }, + { + "u64": 0 + }, + { + "u64": 1000 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "proposal" + } + ], + "data": { + "vec": [ + { + "u64": 2 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + }, + { + "bytes": "697066733a2f2f516d54657374313233" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "create_proposal" + } + ], + "data": { + "u64": 2 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "batch_vote" + } + ], + "data": { + "vec": [ + { + "vec": [ + { + "vec": [ + { + "u64": 0 + }, + { + "bool": true + } + ] + }, + { + "vec": [ + { + "u64": 1 + }, + { + "bool": false + } + ] + }, + { + "vec": [ + { + "u64": 2 + }, + { + "bool": true + } + ] + } + ] + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "vote" + } + ], + "data": { + "vec": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "bool": true + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "vote" + } + ], + "data": { + "vec": [ + { + "u64": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "bool": false + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "vote" + } + ], + "data": { + "vec": [ + { + "u64": 2 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "bool": true + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "batch_ok" + } + ], + "data": { + "vec": [ + { + "u32": 3 + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "batch_vote" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "failed" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "successful" + }, + "val": { + "u32": 3 + } + }, + { + "key": { + "symbol": "total" + }, + "val": { + "u32": 3 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "has_voted" + } + ], + "data": { + "vec": [ + { + "u64": 0 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "has_voted" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "has_voted" + } + ], + "data": { + "vec": [ + { + "u64": 1 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "has_voted" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "has_voted" + } + ], + "data": { + "vec": [ + { + "u64": 2 + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "has_voted" + } + ], + "data": { + "bool": true + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_proposal" + } + ], + "data": { + "u64": 0 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_proposal" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "creator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "end_time" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "no_votes" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "payload_ref" + }, + "val": { + "bytes": "697066733a2f2f516d54657374313233" + } + }, + { + "key": { + "symbol": "start_time" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "yes_votes" + }, + "val": { + "u32": 1 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "symbol": "get_proposal" + } + ], + "data": { + "u64": 1 + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000001", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_proposal" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "creator" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + } + }, + { + "key": { + "symbol": "end_time" + }, + "val": { + "u64": 1000 + } + }, + { + "key": { + "symbol": "executed" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u64": 1 + } + }, + { + "key": { + "symbol": "no_votes" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "payload_ref" + }, + "val": { + "bytes": "697066733a2f2f516d54657374313233" + } + }, + { + "key": { + "symbol": "start_time" + }, + "val": { + "u64": 0 + } + }, + { + "key": { + "symbol": "yes_votes" + }, + "val": { + "u32": 0 + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/contracts/profit-distribution/src/errors.rs b/contracts/profit-distribution/src/errors.rs index 9290786..8a5d738 100644 --- a/contracts/profit-distribution/src/errors.rs +++ b/contracts/profit-distribution/src/errors.rs @@ -13,4 +13,6 @@ pub enum ContractError { AlreadyClaimed = 7, Unauthorized = 8, InvalidAmount = 9, + BatchLimitExceeded = 10, + BatchEmpty = 11, } diff --git a/contracts/profit-distribution/src/lib.rs b/contracts/profit-distribution/src/lib.rs index 445f9b7..5f645b0 100644 --- a/contracts/profit-distribution/src/lib.rs +++ b/contracts/profit-distribution/src/lib.rs @@ -6,7 +6,7 @@ // - Dividend claiming mechanism #![no_std] -use soroban_sdk::{contract, contractimpl, contractmeta, token::TokenClient, Address, Env, Map}; +use soroban_sdk::{contract, contractimpl, contractmeta, token::TokenClient, Address, Env, Map, Vec}; mod errors; mod events; @@ -23,6 +23,12 @@ use crate::{ types::InvestorShare, }; +use shared::{ + constants::MAX_BATCH_SIZE, + events::{BATCH_COMPLETED, BATCH_ITEM_FAILED}, + types::BatchResult, +}; + const PRECISION: i128 = 1_000_000_000_000; contractmeta!(key = "name", val = "Profit Distribution Contract"); @@ -185,4 +191,103 @@ impl ProfitDistribution { pub fn get_admin(env: Env) -> Option
{ get_admin(&env) } + + // ==================== Batch Operations ==================== + + /// Claim dividends from multiple projects in a single call + /// + /// # Arguments + /// * `project_ids` - Vec of project IDs to claim from + /// * `investor` - Address of the investor + /// + /// # Returns + /// * `(BatchResult, i128)` - Batch result and total amount claimed + pub fn batch_claim_dividends( + env: Env, + project_ids: Vec, + investor: Address, + ) -> Result<(BatchResult, i128), ContractError> { + let count = project_ids.len() as u32; + if count == 0 { + return Err(ContractError::BatchEmpty); + } + if count > MAX_BATCH_SIZE { + return Err(ContractError::BatchLimitExceeded); + } + + // Authenticate investor once + investor.require_auth(); + + let mut successful: u32 = 0; + let mut failed: u32 = 0; + let mut total_claimed: i128 = 0; + + for i in 0..project_ids.len() { + let project_id = project_ids.get(i).unwrap(); + + // Get project token - skip if not initialized + let token_address = match get_project_token(&env, project_id) { + Some(t) => t, + None => { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), project_id); + continue; + } + }; + + // Get investor share - skip if not registered + let mut share = match get_investor_share(&env, project_id, &investor) { + Some(s) => s, + None => { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), project_id); + continue; + } + }; + + let current_acc = get_acc_profit_per_share(&env, project_id); + + // Calculate pending amount + let pending = (share.share_percentage as i128 + * (current_acc - share.accumulated_at_last_update)) + / PRECISION; + let claimable = share.claimable_amount + pending; + + // Skip if nothing to claim + if claimable <= 0 { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), project_id); + continue; + } + + // Update user state + share.claimable_amount = 0; + share.accumulated_at_last_update = current_acc; + share.total_claimed += claimable; + set_investor_share(&env, project_id, &investor, &share); + + // Transfer funds + let token_client = TokenClient::new(&env, &token_address); + token_client.transfer(&env.current_contract_address(), &investor, &claimable); + + emit_claim_event(&env, project_id, &investor, claimable); + total_claimed += claimable; + successful += 1; + } + + env.events() + .publish((BATCH_COMPLETED,), (successful, failed)); + + Ok(( + BatchResult { + total: count, + successful, + failed, + }, + total_claimed, + )) + } } diff --git a/contracts/project-launch/src/lib.rs b/contracts/project-launch/src/lib.rs index 1ba5d32..2d2fe48 100644 --- a/contracts/project-launch/src/lib.rs +++ b/contracts/project-launch/src/lib.rs @@ -1,18 +1,17 @@ #![no_std] -use soroban_sdk::{contract, contractimpl, contracttype, token::TokenClient, Address, Bytes, Env}; +use soroban_sdk::{ + contract, contracterror, contractimpl, contracttype, token::TokenClient, Address, Bytes, Env, + Vec, + contract, contractimpl, contracttype, token::TokenClient, Address, Bytes, Env, +}; use shared::{ - constants::{ - MAX_PROJECT_DURATION, MIN_CONTRIBUTION, MIN_FUNDING_GOAL, MIN_PROJECT_DURATION, - RESUME_TIME_DELAY, UPGRADE_TIME_LOCK_SECS, - }, + constants::{MAX_BATCH_SIZE, MAX_PROJECT_DURATION, MIN_CONTRIBUTION, MIN_FUNDING_GOAL, MIN_PROJECT_DURATION}, errors::Error, - events::{ - CONTRACT_PAUSED, CONTRACT_RESUMED, CONTRIBUTION_MADE, PROJECT_CREATED, PROJECT_FAILED, - REFUND_ISSUED, UPGRADE_CANCELLED, UPGRADE_EXECUTED, UPGRADE_SCHEDULED, - }, - types::{Jurisdiction, PauseState, PendingUpgrade}, + events::{BATCH_COMPLETED, BATCH_ITEM_FAILED, CONTRIBUTION_MADE, PROJECT_CREATED}, + types::BatchResult, + events::{CONTRIBUTION_MADE, PROJECT_CREATED, PROJECT_FAILED, REFUND_ISSUED}, utils::verify_future_timestamp, }; use soroban_sdk::BytesN; @@ -298,129 +297,114 @@ impl ProjectLaunch { env.storage().instance().get(&DataKey::Admin) } - /// Check if project deadline has passed and mark it as failed if funding goal not met - /// This can be called by anyone to trigger the failure status update - pub fn mark_project_failed(env: Env, project_id: u64) -> Result<(), Error> { - // Get project - let mut project: Project = env - .storage() - .instance() - .get(&(DataKey::Project, project_id)) - .ok_or(Error::ProjectNotFound)?; - - let current_time = env.ledger().timestamp(); + // ==================== Batch Operations ==================== - // Check if deadline has passed - if current_time <= project.deadline { - return Err(Error::InvalidInput); // Deadline hasn't passed yet - } - - // Check if project is already failed or completed - if project.status == ProjectStatus::Failed || project.status == ProjectStatus::Completed { - return Err(Error::InvalidProjectStatus); - } - - // Check if failure has already been processed - if env - .storage() - .instance() - .has(&(DataKey::ProjectFailureProcessed, project_id)) - { - return Err(Error::InvalidProjectStatus); + /// Contribute to multiple projects in a single call + /// + /// # Arguments + /// * `contributions` - Vec of (project_id, amount) tuples + /// * `contributor` - Address of the contributor + pub fn batch_contribute( + env: Env, + contributions: Vec<(u64, i128)>, + contributor: Address, + ) -> Result { + let count = contributions.len() as u32; + if count == 0 { + return Err(Error::BatchEmpty); } - - // Check if funding goal was met - if project.total_raised >= project.funding_goal { - // Project succeeded, mark as completed instead - project.status = ProjectStatus::Completed; - } else { - // Project failed due to insufficient funding - project.status = ProjectStatus::Failed; - // Emit event to indicate project failure - env.events().publish((PROJECT_FAILED,), project_id); + if count > MAX_BATCH_SIZE { + return Err(Error::BatchLimitExceeded); } - // Store updated project - env.storage() - .instance() - .set(&(DataKey::Project, project_id), &project); + // Authenticate contributor once + contributor.require_auth(); - // Mark that failure check has been processed - env.storage() - .instance() - .set(&(DataKey::ProjectFailureProcessed, project_id), &true); + let current_time = env.ledger().timestamp(); + let mut successful: u32 = 0; + let mut failed: u32 = 0; + + for i in 0..contributions.len() { + let (project_id, amount) = contributions.get(i).unwrap(); + + // Validate minimum contribution + if amount < MIN_CONTRIBUTION { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), project_id); + continue; + } - Ok(()) - } + // Get project - skip if not found + let mut project: Project = match env + .storage() + .instance() + .get(&(DataKey::Project, project_id)) + { + Some(p) => p, + None => { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), project_id); + continue; + } + }; + + // Skip if not active + if project.status != ProjectStatus::Active { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), project_id); + continue; + } - /// Refund a specific contributor - /// Can be called by the contributor or any permissionless caller - pub fn refund_contributor( - env: Env, - project_id: u64, - contributor: Address, - ) -> Result { - // Get project - let project: Project = env - .storage() - .instance() - .get(&(DataKey::Project, project_id)) - .ok_or(Error::ProjectNotFound)?; + // Skip if past deadline + if current_time >= project.deadline { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), project_id); + continue; + } - // Ensure project is in failed state - if project.status != ProjectStatus::Failed { - return Err(Error::ProjectNotActive); - } + // Update project totals + project.total_raised += amount; + env.storage() + .instance() + .set(&(DataKey::Project, project_id), &project); - // Check if refund has already been processed for this contributor - let refund_key = (DataKey::RefundProcessed, project_id, contributor.clone()); - if env.storage().instance().has(&refund_key) { - return Err(Error::InvalidInput); // Already refunded - } + // Perform token transfer + let token_client = TokenClient::new(&env, &project.token); + token_client.transfer(&contributor, &env.current_contract_address(), &amount); - // Get contribution amount - let contribution_key = (DataKey::ContributionAmount, project_id, contributor.clone()); - let contribution_amount: i128 = env - .storage() - .persistent() - .get(&contribution_key) - .unwrap_or(0); + // Store aggregated contribution + let contribution_key = + (DataKey::ContributionAmount, project_id, contributor.clone()); + let current_contribution: i128 = env + .storage() + .persistent() + .get(&contribution_key) + .unwrap_or(0); - if contribution_amount <= 0 { - return Err(Error::InvalidInput); // No contribution to refund + let new_contribution = current_contribution.checked_add(amount).unwrap(); + env.storage() + .persistent() + .set(&contribution_key, &new_contribution); + + env.events().publish( + (CONTRIBUTION_MADE,), + (project_id, contributor.clone(), amount, project.total_raised), + ); + successful += 1; } - // Transfer tokens back to contributor - let token_client = TokenClient::new(&env, &project.token); - token_client.transfer( - &env.current_contract_address(), - &contributor, - &contribution_amount, - ); - - // Mark refund as processed - env.storage().instance().set(&refund_key, &true); - - // Emit refund event - env.events().publish( - (REFUND_ISSUED,), - (project_id, contributor, contribution_amount), - ); - - Ok(contribution_amount) - } - - /// Check if a contributor has been refunded for a project - pub fn is_refunded(env: Env, project_id: u64, contributor: Address) -> bool { - let refund_key = (DataKey::RefundProcessed, project_id, contributor); - env.storage().instance().has(&refund_key) - } + env.events() + .publish((BATCH_COMPLETED,), (successful, failed)); - /// Check if project failure has been processed - pub fn is_failure_processed(env: Env, project_id: u64) -> bool { - env.storage() - .instance() - .has(&(DataKey::ProjectFailureProcessed, project_id)) + Ok(BatchResult { + total: count, + successful, + failed, + }) } // ---------- Pause (emergency) ---------- diff --git a/contracts/reputation/src/lib.rs b/contracts/reputation/src/lib.rs index 893c24e..82bbce8 100644 --- a/contracts/reputation/src/lib.rs +++ b/contracts/reputation/src/lib.rs @@ -1,8 +1,11 @@ #![no_std] -use shared::constants::{REPUTATION_MAX, REPUTATION_MIN, REPUTATION_START}; +use shared::constants::{MAX_BATCH_SIZE, REPUTATION_MAX, REPUTATION_MIN, REPUTATION_START}; use shared::errors::Error; -use shared::events::{BADGE_EARNED, REPUTATION_UPDATED, USER_REGISTERED}; +use shared::events::{ + BADGE_EARNED, BATCH_COMPLETED, BATCH_ITEM_FAILED, REPUTATION_UPDATED, USER_REGISTERED, +}; +use shared::types::BatchResult; use soroban_sdk::{contract, contractimpl, contracttype, Address, Env, Vec}; /// Storage keys for the reputation contract @@ -253,6 +256,136 @@ impl ReputationContract { } false } + + // ==================== Batch Operations ==================== + + /// Update reputation scores for multiple users in one call (admin only) + /// + /// # Arguments + /// * `updates` - Vec of (user_address, delta) tuples + pub fn batch_update_scores( + env: Env, + updates: Vec<(Address, i128)>, + ) -> Result { + let count = updates.len() as u32; + if count == 0 { + return Err(Error::BatchEmpty); + } + if count > MAX_BATCH_SIZE { + return Err(Error::BatchLimitExceeded); + } + + // Check initialization and auth once + Self::require_initialized(&env)?; + let admin = Self::get_admin(&env)?; + admin.require_auth(); + + let mut successful: u32 = 0; + let mut failed: u32 = 0; + + for i in 0..updates.len() { + let (user, delta) = updates.get(i).unwrap(); + + // Get existing profile - skip if not registered + let mut profile = match Self::get_profile_internal(&env, &user) { + Ok(p) => p, + Err(_) => { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), user.clone()); + continue; + } + }; + + // Calculate and clamp score + let new_score = profile.score.saturating_add(delta); + let clamped_score = new_score.max(REPUTATION_MIN).min(REPUTATION_MAX); + + profile.score = clamped_score; + env.storage() + .persistent() + .set(&DataKey::Profile(user.clone()), &profile); + + env.events() + .publish((REPUTATION_UPDATED,), (user, clamped_score)); + successful += 1; + } + + env.events() + .publish((BATCH_COMPLETED,), (successful, failed)); + + Ok(BatchResult { + total: count, + successful, + failed, + }) + } + + /// Award badges to multiple users in one call (admin only) + /// + /// # Arguments + /// * `awards` - Vec of (user_address, badge_type) tuples + pub fn batch_award_badges( + env: Env, + awards: Vec<(Address, BadgeType)>, + ) -> Result { + let count = awards.len() as u32; + if count == 0 { + return Err(Error::BatchEmpty); + } + if count > MAX_BATCH_SIZE { + return Err(Error::BatchLimitExceeded); + } + + // Check initialization and auth once + Self::require_initialized(&env)?; + let admin = Self::get_admin(&env)?; + admin.require_auth(); + + let mut successful: u32 = 0; + let mut failed: u32 = 0; + + for i in 0..awards.len() { + let (user, badge) = awards.get(i).unwrap(); + + // Get existing profile - skip if not registered + let mut profile = match Self::get_profile_internal(&env, &user) { + Ok(p) => p, + Err(_) => { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), user.clone()); + continue; + } + }; + + // Skip if badge already awarded + if Self::has_badge(&profile.badges, badge) { + failed += 1; + env.events() + .publish((BATCH_ITEM_FAILED,), user.clone()); + continue; + } + + profile.badges.push_back(badge); + env.storage() + .persistent() + .set(&DataKey::Profile(user.clone()), &profile); + + env.events() + .publish((BADGE_EARNED,), (user, badge as u32)); + successful += 1; + } + + env.events() + .publish((BATCH_COMPLETED,), (successful, failed)); + + Ok(BatchResult { + total: count, + successful, + failed, + }) + } } #[cfg(test)] @@ -510,4 +643,100 @@ mod tests { let profile = client.get_profile(&user); assert_eq!(profile.badges.len(), 1); } + + // ==================== Batch Operation Tests ==================== + + #[test] + fn test_batch_update_scores() { + let (env, admin, client, _) = setup_env(); + client.initialize(&admin); + + let user1 = Address::generate(&env); + let user2 = Address::generate(&env); + let user3 = Address::generate(&env); + client.register_user(&user1); + client.register_user(&user2); + client.register_user(&user3); + + let mut updates = Vec::new(&env); + updates.push_back((user1.clone(), 50_i128)); + updates.push_back((user2.clone(), -30_i128)); + updates.push_back((user3.clone(), 100_i128)); + + let result = client.batch_update_scores(&updates); + assert_eq!(result.total, 3); + assert_eq!(result.successful, 3); + assert_eq!(result.failed, 0); + + assert_eq!(client.get_profile(&user1).score, REPUTATION_START + 50); + assert_eq!(client.get_profile(&user2).score, REPUTATION_START - 30); + assert_eq!(client.get_profile(&user3).score, REPUTATION_START + 100); + } + + #[test] + fn test_batch_update_scores_partial_failure() { + let (env, admin, client, user) = setup_env(); + client.initialize(&admin); + client.register_user(&user); + + let unregistered = Address::generate(&env); + + let mut updates = Vec::new(&env); + updates.push_back((user.clone(), 50_i128)); + updates.push_back((unregistered.clone(), 100_i128)); // not registered + + let result = client.batch_update_scores(&updates); + assert_eq!(result.total, 2); + assert_eq!(result.successful, 1); + assert_eq!(result.failed, 1); + + assert_eq!(client.get_profile(&user).score, REPUTATION_START + 50); + } + + #[test] + fn test_batch_award_badges() { + let (env, admin, client, _) = setup_env(); + client.initialize(&admin); + + let user1 = Address::generate(&env); + let user2 = Address::generate(&env); + client.register_user(&user1); + client.register_user(&user2); + + let mut awards = Vec::new(&env); + awards.push_back((user1.clone(), BadgeType::Contributor)); + awards.push_back((user2.clone(), BadgeType::EarlyAdopter)); + + let result = client.batch_award_badges(&awards); + assert_eq!(result.total, 2); + assert_eq!(result.successful, 2); + assert_eq!(result.failed, 0); + + assert_eq!(client.get_profile(&user1).badges.len(), 1); + assert_eq!(client.get_profile(&user2).badges.len(), 1); + } + + #[test] + fn test_batch_award_badges_partial_failure() { + let (env, admin, client, user) = setup_env(); + client.initialize(&admin); + client.register_user(&user); + + // Award a badge first + client.award_badge(&user, &BadgeType::Contributor); + + let user2 = Address::generate(&env); + client.register_user(&user2); + + let mut awards = Vec::new(&env); + awards.push_back((user.clone(), BadgeType::Contributor)); // duplicate - should fail + awards.push_back((user2.clone(), BadgeType::TopInvestor)); // should succeed + + let result = client.batch_award_badges(&awards); + assert_eq!(result.total, 2); + assert_eq!(result.successful, 1); + assert_eq!(result.failed, 1); + + assert_eq!(client.get_profile(&user2).badges.len(), 1); + } } diff --git a/contracts/reputation/test_snapshots/tests/test_batch_award_badges.1.json b/contracts/reputation/test_snapshots/tests/test_batch_award_badges.1.json new file mode 100644 index 0000000..48983cb --- /dev/null +++ b/contracts/reputation/test_snapshots/tests/test_batch_award_badges.1.json @@ -0,0 +1,1064 @@ +{ + "generators": { + "address": 5, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "initialize", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "register_user", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "register_user", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "batch_award_badges", + "args": [ + { + "vec": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u32": 0 + } + ] + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "u32": 3 + } + ] + } + ] + } + ] + } + }, + "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_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": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [ + { + "u32": 0 + } + ] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [ + { + "u32": 3 + } + ] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "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": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Initialized" + } + ] + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_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": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "initialize" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "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": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "register_user" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "user_reg" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "register_user" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "register_user" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "user_reg" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "register_user" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "batch_award_badges" + } + ], + "data": { + "vec": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u32": 0 + } + ] + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "u32": 3 + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "badge" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "badge" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "u32": 3 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "batch_ok" + } + ], + "data": { + "vec": [ + { + "u32": 2 + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "batch_award_badges" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "failed" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "successful" + }, + "val": { + "u32": 2 + } + }, + { + "key": { + "symbol": "total" + }, + "val": { + "u32": 2 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [ + { + "u32": 0 + } + ] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [ + { + "u32": 3 + } + ] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/contracts/reputation/test_snapshots/tests/test_batch_award_badges_partial_failure.1.json b/contracts/reputation/test_snapshots/tests/test_batch_award_badges_partial_failure.1.json new file mode 100644 index 0000000..cd4e946 --- /dev/null +++ b/contracts/reputation/test_snapshots/tests/test_batch_award_badges_partial_failure.1.json @@ -0,0 +1,1111 @@ +{ + "generators": { + "address": 4, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "initialize", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "register_user", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "award_badge", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 0 + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "register_user", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "batch_award_badges", + "args": [ + { + "vec": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 0 + } + ] + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u32": 2 + } + ] + } + ] + } + ] + } + }, + "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_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": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "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": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [ + { + "u32": 0 + } + ] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [ + { + "u32": 2 + } + ] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "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": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Initialized" + } + ] + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 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": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "initialize" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "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": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "register_user" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "user_reg" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "register_user" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "award_badge" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "badge" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "award_badge" + } + ], + "data": "void" + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "register_user" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "user_reg" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "register_user" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "batch_award_badges" + } + ], + "data": { + "vec": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "u32": 0 + } + ] + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u32": 2 + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "batch_fl" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "badge" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "u32": 2 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "batch_ok" + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "batch_award_badges" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "failed" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "successful" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "total" + }, + "val": { + "u32": 2 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [ + { + "u32": 2 + } + ] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/contracts/reputation/test_snapshots/tests/test_batch_update_scores.1.json b/contracts/reputation/test_snapshots/tests/test_batch_update_scores.1.json new file mode 100644 index 0000000..a9f796e --- /dev/null +++ b/contracts/reputation/test_snapshots/tests/test_batch_update_scores.1.json @@ -0,0 +1,1422 @@ +{ + "generators": { + "address": 6, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "initialize", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "register_user", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "register_user", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "register_user", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "batch_update_scores", + "args": [ + { + "vec": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 50 + } + } + ] + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "i128": { + "hi": -1, + "lo": 18446744073709551586 + } + } + ] + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + ] + } + ] + } + }, + "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_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": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 2032731177588607455 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 150 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 70 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 200 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "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": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Initialized" + } + ] + }, + "val": { + "bool": true + } + } + ] + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", + "key": { + "ledger_key_nonce": { + "nonce": 5541220902715666415 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", + "key": { + "ledger_key_nonce": { + "nonce": 4837995959683129791 + } + }, + "durability": "temporary", + "val": "void" + } + }, + "ext": "v0" + }, + 6311999 + ] + ], + [ + { + "contract_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": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "initialize" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "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": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "register_user" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "user_reg" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "register_user" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "register_user" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "user_reg" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "register_user" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "register_user" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "user_reg" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "register_user" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "batch_update_scores" + } + ], + "data": { + "vec": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 50 + } + } + ] + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "i128": { + "hi": -1, + "lo": 18446744073709551586 + } + } + ] + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "rep_up" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 150 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "rep_up" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + }, + { + "i128": { + "hi": 0, + "lo": 70 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "rep_up" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + }, + { + "i128": { + "hi": 0, + "lo": 200 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "batch_ok" + } + ], + "data": { + "vec": [ + { + "u32": 3 + }, + { + "u32": 0 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "batch_update_scores" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "failed" + }, + "val": { + "u32": 0 + } + }, + { + "key": { + "symbol": "successful" + }, + "val": { + "u32": 3 + } + }, + { + "key": { + "symbol": "total" + }, + "val": { + "u32": 3 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 150 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 70 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM" + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 200 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/contracts/reputation/test_snapshots/tests/test_batch_update_scores_partial_failure.1.json b/contracts/reputation/test_snapshots/tests/test_batch_update_scores_partial_failure.1.json new file mode 100644 index 0000000..67caca4 --- /dev/null +++ b/contracts/reputation/test_snapshots/tests/test_batch_update_scores_partial_failure.1.json @@ -0,0 +1,756 @@ +{ + "generators": { + "address": 4, + "nonce": 0 + }, + "auth": [ + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "initialize", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "register_user", + "args": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + } + }, + "sub_invocations": [] + } + ] + ], + [ + [ + "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + { + "function": { + "contract_fn": { + "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "function_name": "batch_update_scores", + "args": [ + { + "vec": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 50 + } + } + ] + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + ] + } + ] + } + }, + "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_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": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "ledger_key_nonce": { + "nonce": 1033654523790656264 + } + }, + "durability": "temporary" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "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_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", + "key": { + "vec": [ + { + "symbol": "Profile" + }, + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + ] + }, + "durability": "persistent", + "val": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 150 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "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": { + "vec": [ + { + "symbol": "Admin" + } + ] + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + }, + { + "key": { + "vec": [ + { + "symbol": "Initialized" + } + ] + }, + "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": [ + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "initialize" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "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": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "register_user" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "user_reg" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "register_user" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 100 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "batch_update_scores" + } + ], + "data": { + "vec": [ + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 50 + } + } + ] + }, + { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + }, + { + "i128": { + "hi": 0, + "lo": 100 + } + } + ] + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "rep_up" + } + ], + "data": { + "vec": [ + { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + }, + { + "i128": { + "hi": 0, + "lo": 150 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "batch_fl" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "contract", + "body": { + "v0": { + "topics": [ + { + "symbol": "batch_ok" + } + ], + "data": { + "vec": [ + { + "u32": 1 + }, + { + "u32": 1 + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "batch_update_scores" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "failed" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "successful" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "total" + }, + "val": { + "u32": 2 + } + } + ] + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": null, + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_call" + }, + { + "bytes": "0000000000000000000000000000000000000000000000000000000000000003" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + } + }, + "failed_call": false + }, + { + "event": { + "ext": "v0", + "contract_id": "0000000000000000000000000000000000000000000000000000000000000003", + "type_": "diagnostic", + "body": { + "v0": { + "topics": [ + { + "symbol": "fn_return" + }, + { + "symbol": "get_profile" + } + ], + "data": { + "map": [ + { + "key": { + "symbol": "badges" + }, + "val": { + "vec": [] + } + }, + { + "key": { + "symbol": "score" + }, + "val": { + "i128": { + "hi": 0, + "lo": 150 + } + } + }, + { + "key": { + "symbol": "user" + }, + "val": { + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" + } + } + ] + } + } + } + }, + "failed_call": false + } + ] +} \ No newline at end of file diff --git a/contracts/shared/src/constants.rs b/contracts/shared/src/constants.rs index 2cab103..21546bd 100644 --- a/contracts/shared/src/constants.rs +++ b/contracts/shared/src/constants.rs @@ -36,18 +36,13 @@ pub const GOVERNANCE_QUORUM: u32 = 2000; /// Voting period duration (7 days in seconds) pub const VOTING_PERIOD: u64 = 604800; -// Max & Min threshold consts -pub const MIN_APPROVAL_THRESHOLD: u32 = 5100; // 51% minimum -pub const MAX_APPROVAL_THRESHOLD: u32 = 10000; // 100% maximum -pub const RESUME_TIME_DELAY: u64 = 86400; // 24 hours in seconds - -/// Minimum delay before a scheduled upgrade can be executed (48 hours) -pub const UPGRADE_TIME_LOCK_SECS: u64 = 172800; // 48 * 3600 - -// Oracle defaults -/// Maximum number of oracles allowed per feed -pub const ORACLE_MAX_ORACLES_PER_FEED: u32 = 16; -/// Default heartbeat for active feeds (seconds) -pub const ORACLE_DEFAULT_HEARTBEAT: u64 = 60; -/// Maximum allowed deviation between consecutive values (basis points) -pub const ORACLE_MAX_DEVIATION_BPS: u32 = 5000; +pub const ESCROW_INITIALIZED: Symbol = symbol_short!("esc_init"); +pub const FUNDS_LOCKED: Symbol = symbol_short!("f_lock"); +pub const MILESTONE_CREATED: Symbol = symbol_short!("mile_cr"); +pub const MILESTONE_SUBMITTED: Symbol = symbol_short!("mile_sub"); +pub const MILESTONE_APPROVED: Symbol = symbol_short!("mile_apr"); +pub const MILESTONE_REJECTED: Symbol = symbol_short!("mile_rej"); +pub const FUNDS_RELEASED: Symbol = symbol_short!("fund_rel"); + +/// Maximum number of items in a batch operation +pub const MAX_BATCH_SIZE: u32 = 20; diff --git a/contracts/shared/src/errors.rs b/contracts/shared/src/errors.rs index f6ce9f1..febf819 100644 --- a/contracts/shared/src/errors.rs +++ b/contracts/shared/src/errors.rs @@ -69,5 +69,8 @@ pub enum Error { InvalidDeadline = 1001, ProjectNotFound = 1002, ContributionTooLow = 1003, - IdentityNotVerified = 1004, + + // Batch operation errors (800-899) + BatchLimitExceeded = 800, + BatchEmpty = 801, } diff --git a/contracts/shared/src/events.rs b/contracts/shared/src/events.rs index ae5cd90..98cd2e2 100644 --- a/contracts/shared/src/events.rs +++ b/contracts/shared/src/events.rs @@ -63,17 +63,7 @@ pub const RELAYER_ADDED: Symbol = symbol_short!("rel_add"); pub const RELAYER_REMOVED: Symbol = symbol_short!("rel_rem"); pub const BRIDGE_TX_CONFIRMED: Symbol = symbol_short!("tx_conf"); pub const BRIDGE_TX_FAILED: Symbol = symbol_short!("tx_fail"); -pub const CONTRACT_PAUSED: Symbol = symbol_short!("esc_pause"); -pub const CONTRACT_RESUMED: Symbol = symbol_short!("esc_resum"); -// Upgrade events -pub const UPGRADE_SCHEDULED: Symbol = symbol_short!("upg_sched"); -pub const UPGRADE_EXECUTED: Symbol = symbol_short!("upg_exec"); -pub const UPGRADE_CANCELLED: Symbol = symbol_short!("upg_canc"); - -// Oracle events -pub const ORACLE_FEED_CREATED: Symbol = symbol_short!("or_feed"); -pub const ORACLE_FEED_UPDATED: Symbol = symbol_short!("or_upd"); -pub const ORACLE_ORACLE_STAKED: Symbol = symbol_short!("or_stak"); -pub const ORACLE_ORACLE_UNSTAKED: Symbol = symbol_short!("or_unst"); -pub const ORACLE_SLASHED: Symbol = symbol_short!("or_slsh"); +// Batch operation events +pub const BATCH_COMPLETED: Symbol = symbol_short!("batch_ok"); +pub const BATCH_ITEM_FAILED: Symbol = symbol_short!("batch_fl"); diff --git a/contracts/shared/src/types.rs b/contracts/shared/src/types.rs index a050d64..e89084b 100644 --- a/contracts/shared/src/types.rs +++ b/contracts/shared/src/types.rs @@ -21,6 +21,15 @@ pub struct FeeConfig { pub fee_recipient: Address, // Address to receive fees } +/// Result of a batch operation +#[contracttype] +#[derive(Clone, Debug)] +pub struct BatchResult { + pub total: u32, // Total items in the batch + pub successful: u32, // Number of items processed successfully + pub failed: u32, // Number of items that failed validation +} + /// Token information #[contracttype] #[derive(Clone)]