Skip to content

Commit

Permalink
Merge pull request #217 from NinoLipartiia/tick-bug
Browse files Browse the repository at this point in the history
Tick deletes only active agents
  • Loading branch information
TrevorJTClarke authored Dec 17, 2022
2 parents 0687460 + 2e02ae1 commit d302d77
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 11 deletions.
2 changes: 1 addition & 1 deletion checksum
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
de7f6716cf0380e7eaff2440d24dada99fe054aaf51e190b80c5a8ebf35c97d5 cw_croncat.wasm
14994ed3c237597f9ece434ce72387cd04525ff5b27a90909f9d881cae4d96db cw_croncat.wasm
de2d1a0c648e41760020dd261f818da085c358240059acf85128f60eb0e05db2 cw_rules.wasm
17 changes: 11 additions & 6 deletions contracts/cw-croncat/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use crate::error::ContractError;
use crate::helpers::proxy_call_submsgs_price;
use crate::state::{Config, CwCroncat, QueueItem, TaskInfo};
use cosmwasm_std::{
from_binary, Addr, Deps, DepsMut, Env, MessageInfo, Order, Reply, Response, StdResult, Storage,
from_binary, Addr, Attribute, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult,
Storage,
};
use cw_croncat_core::traits::{FindAndMutate, Intervals};
use cw_croncat_core::types::{Agent, Interval, SlotType, Task};
Expand Down Expand Up @@ -528,11 +529,8 @@ impl<'a> CwCroncat<'a> {
let cfg = self.config.load(deps.storage)?;
let mut attributes = vec![];
let mut submessages = vec![];
for agent_id in self
.agents
.keys(deps.storage, None, None, Order::Ascending)
.collect::<StdResult<Vec<Addr>>>()?
{

for agent_id in self.agent_active_queue.load(deps.storage)? {
let agent = self.agents.load(deps.storage, &agent_id)?;
if current_slot > agent.last_executed_slot + cfg.agents_eject_threshold {
let resp = self
Expand All @@ -543,6 +541,13 @@ impl<'a> CwCroncat<'a> {
submessages.extend_from_slice(&resp.messages);
}
}

// Check if there isn't any active or pending agents
if self.agent_active_queue.load(deps.storage)?.is_empty()
&& self.agent_pending_queue.is_empty(deps.storage)?
{
attributes.push(Attribute::new("lifecycle", "tick_failure"))
}
let response = Response::new()
.add_attribute("method", "tick")
.add_attributes(attributes)
Expand Down
106 changes: 102 additions & 4 deletions contracts/cw-croncat/src/tests/manager.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::contract::{GAS_ACTION_FEE_JUNO, GAS_BASE_FEE_JUNO, GAS_DENOMINATOR_DEFAULT_JUNO};
use crate::tests::helpers::{
add_1000_blocks, add_little_time, add_one_duration_of_time, cw4_template, proper_instantiate,
AGENT3,
AGENT1, AGENT2, AGENT3,
};
use crate::ContractError;
use cosmwasm_std::{
Expand Down Expand Up @@ -1854,7 +1854,7 @@ fn tick() {
owner_id: None,
agent_fee: None,
min_tasks_per_agent: None,
agents_eject_threshold: Some(1000), // allow to miss 100 slots
agents_eject_threshold: Some(1000), // allow to miss 1000 slots
gas_action_fee: None,
proxy_callback_gas: None,
slot_granularity_time: None,
Expand All @@ -1876,10 +1876,61 @@ fn tick() {
app.execute_contract(Addr::unchecked(AGENT0), contract_addr.clone(), &msg, &[])
.unwrap();

// Add 1001 blocks and call tick
app.update_block(add_1000_blocks);
app.update_block(add_little_time);
let tick_msg = ExecuteMsg::Tick {};
let res = app
.execute_contract(
Addr::unchecked(ANYONE),
contract_addr.clone(),
&tick_msg,
&vec![],
)
.unwrap();

// Check attributes
assert!(res.events.iter().any(|ev| ev
.attributes
.iter()
.any(|attr| attr.key == "method" && attr.value == "tick")));
assert!(res.events.iter().any(|ev| ev
.attributes
.iter()
.any(|attr| attr.key == "method" && attr.value == "unregister_agent")));
assert!(res.events.iter().any(|ev| ev
.attributes
.iter()
.any(|attr| attr.key == "account_id" && attr.value == AGENT0)));
assert!(res.events.iter().any(|ev| ev
.attributes
.iter()
.any(|attr| attr.key == "lifecycle" && attr.value == "tick_failure")));

// The agent missed 1001 blocks and he was unregistered
// Pending agents weren't deleted
let agents: GetAgentIdsResponse = app
.wrap()
.query_wasm_smart(contract_addr.clone(), &QueryMsg::GetAgentIds {})
.unwrap();
assert!(agents.active.is_empty());
assert!(agents.pending.is_empty());

// quick agent register
app.execute_contract(Addr::unchecked(AGENT0), contract_addr.clone(), &msg, &[])
.unwrap();

// Two agents added to the pending queue
app.execute_contract(Addr::unchecked(AGENT1), contract_addr.clone(), &msg, &[])
.unwrap();
app.execute_contract(Addr::unchecked(AGENT2), contract_addr.clone(), &msg, &[])
.unwrap();

// need block advancement
app.update_block(add_little_time);

let tick_msg = ExecuteMsg::Tick {};
// Call tick
// Not enough time passed to delete the agent
let res = app
.execute_contract(
Addr::unchecked(AGENT0),
Expand All @@ -1904,7 +1955,25 @@ fn tick() {
.query_wasm_smart(contract_addr.clone(), &QueryMsg::GetAgentIds {})
.unwrap();
assert_eq!(agents.active.len(), 1);
assert_eq!(agents.pending.len(), 2);

// First pending agent wasn't nominated
let err = app
.execute_contract(
Addr::unchecked(AGENT1),
contract_addr.clone(),
&ExecuteMsg::CheckInAgent {},
&[],
)
.unwrap_err();
assert_eq!(
ContractError::CustomError {
val: "Not accepting new agents".to_string()
},
err.downcast().unwrap()
);

// Add enough time and call tick
app.update_block(add_1000_blocks);
let res = app
.execute_contract(
Expand All @@ -1928,14 +1997,43 @@ fn tick() {
.attributes
.iter()
.any(|attr| attr.key == "account_id" && attr.value == AGENT0)));
assert!(!res.events.iter().any(|ev| ev
.attributes
.iter()
.any(|attr| attr.key == "lifecycle" && attr.value == "tick_failure")));

// The agent missed 1001 blocks and he was unregistered
// Pending agents weren't deleted
let agents: GetAgentIdsResponse = app
.wrap()
.query_wasm_smart(contract_addr.clone(), &QueryMsg::GetAgentIds {})
.unwrap();
assert!(agents.active.is_empty());
assert!(agents.pending.is_empty());
assert_eq!(agents.pending.len(), 2);

// First agent was nominated and can call CheckInAgent
app.execute_contract(
Addr::unchecked(AGENT1),
contract_addr.clone(),
&ExecuteMsg::CheckInAgent {},
&[],
)
.unwrap();
// Second agent wasn't nominated
let err = app
.execute_contract(
Addr::unchecked(AGENT2),
contract_addr.clone(),
&ExecuteMsg::CheckInAgent {},
&[],
)
.unwrap_err();
assert_eq!(
ContractError::CustomError {
val: "Not accepting new agents".to_string()
},
err.downcast().unwrap()
);
}

#[test]
Expand Down

0 comments on commit d302d77

Please sign in to comment.