-
Notifications
You must be signed in to change notification settings - Fork 88
Expand file tree
/
Copy pathexpiration.rs
More file actions
87 lines (81 loc) · 2.63 KB
/
expiration.rs
File metadata and controls
87 lines (81 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use crate::{Allocation, Claim};
use fil_actors_runtime::{
parse_uint_key, ActorError, AsActorError, BatchReturn, BatchReturnGen, MapMap,
};
use fvm_ipld_blockstore::Blockstore;
use fvm_shared::clock::ChainEpoch;
use fvm_shared::error::ExitCode;
use fvm_shared::ActorID;
use log::info;
use serde::de::DeserializeOwned;
use serde::Serialize;
// Something with an expiration epoch.
pub trait Expires {
fn expiration(&self) -> ChainEpoch;
}
impl Expires for Allocation {
fn expiration(&self) -> ChainEpoch {
self.expiration
}
}
impl Expires for Claim {
fn expiration(&self) -> ChainEpoch {
self.term_start + self.term_max
}
}
// Finds all items in a collection for some owner that have expired.
// Returns those items' keys.
pub fn find_expired<T, BS>(
collection: &mut MapMap<BS, T, ActorID, u64>,
owner: ActorID,
curr_epoch: ChainEpoch,
) -> Result<Vec<u64>, ActorError>
where
T: Expires + Serialize + DeserializeOwned + Clone + PartialEq,
BS: Blockstore,
{
let mut found_ids = Vec::<u64>::new();
collection
.for_each_in(owner, |key, record| {
if curr_epoch >= record.expiration() {
let id = parse_uint_key(key)?;
found_ids.push(id);
}
Ok(())
})
.context_code(ExitCode::USR_ILLEGAL_STATE, "failed to iterate over allocations/claims")?;
Ok(found_ids)
}
// Checks each candidate item from the collection for expiration.
// Returns a batch return with OK for expired items, and FORBIDDEN for non-expired.
pub fn check_expired<T, BS>(
collection: &mut MapMap<BS, T, ActorID, u64>,
candidates: &Vec<u64>,
owner: ActorID,
curr_epoch: ChainEpoch,
) -> Result<BatchReturn, ActorError>
where
T: Expires + Serialize + DeserializeOwned + Clone + PartialEq,
BS: Blockstore,
{
let mut ret_gen = BatchReturnGen::new(candidates.len());
for id in candidates {
// Check each specified claim is expired.
let maybe_record = collection.get(owner, *id).context_code(
ExitCode::USR_ILLEGAL_STATE,
"HAMT lookup failure getting allocation/claim",
)?;
if let Some(record) = maybe_record {
if curr_epoch >= record.expiration() {
ret_gen.add_success();
} else {
ret_gen.add_fail(ExitCode::USR_FORBIDDEN);
info!("cannot remove allocation/claim {} that has not expired", id);
}
} else {
ret_gen.add_fail(ExitCode::USR_NOT_FOUND);
info!("allocation/claim references id {} that does not belong to {}", id, owner,);
}
}
Ok(ret_gen.gen())
}