-
Notifications
You must be signed in to change notification settings - Fork 336
/
Copy pathstorage.rs
96 lines (82 loc) · 2.56 KB
/
storage.rs
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
88
89
90
91
92
93
94
95
96
use crate::state::eventlog::Event;
use ic_stable_structures::{
log::{Log as StableLog, NoSuchEntry},
memory_manager::{MemoryId, MemoryManager, VirtualMemory},
DefaultMemoryImpl,
};
use std::cell::RefCell;
const LOG_INDEX_MEMORY_ID: MemoryId = MemoryId::new(0);
const LOG_DATA_MEMORY_ID: MemoryId = MemoryId::new(1);
type VMem = VirtualMemory<DefaultMemoryImpl>;
type EventLog = StableLog<Vec<u8>, VMem, VMem>;
thread_local! {
static MEMORY_MANAGER: RefCell<MemoryManager<DefaultMemoryImpl>> = RefCell::new(
MemoryManager::init(DefaultMemoryImpl::default())
);
/// The log of the ckBTC state modifications.
static EVENTS: RefCell<EventLog> = MEMORY_MANAGER
.with(|m|
RefCell::new(
StableLog::init(
m.borrow().get(LOG_INDEX_MEMORY_ID),
m.borrow().get(LOG_DATA_MEMORY_ID)
).expect("failed to initialize stable log")
)
);
}
pub struct EventIterator {
buf: Vec<u8>,
pos: u64,
}
impl Iterator for EventIterator {
type Item = Event;
fn next(&mut self) -> Option<Event> {
EVENTS.with(|events| {
let events = events.borrow();
match events.read_entry(self.pos, &mut self.buf) {
Ok(()) => {
self.pos = self.pos.saturating_add(1);
Some(decode_event(&self.buf))
}
Err(NoSuchEntry) => None,
}
})
}
fn nth(&mut self, n: usize) -> Option<Event> {
self.pos = self.pos.saturating_add(n as u64);
self.next()
}
}
/// Encodes an event into a byte array.
fn encode_event(event: &Event) -> Vec<u8> {
let mut buf = Vec::new();
ciborium::ser::into_writer(event, &mut buf).expect("failed to encode a minter event");
buf
}
/// # Panics
///
/// This function panics if the event decoding fails.
fn decode_event(buf: &[u8]) -> Event {
ciborium::de::from_reader(buf).expect("failed to decode a minter event")
}
/// Returns an iterator over all minter events.
pub fn events() -> impl Iterator<Item = Event> {
EventIterator {
buf: vec![],
pos: 0,
}
}
/// Returns the current number of events in the log.
pub fn count_events() -> u64 {
EVENTS.with(|events| events.borrow().len())
}
/// Records a new minter event.
pub fn record_event(event: &Event) {
let bytes = encode_event(event);
EVENTS.with(|events| {
events
.borrow()
.append(&bytes)
.expect("failed to append an entry to the event log")
});
}