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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
use serde::{Deserialize, Serialize};
use solana_program::clock::UnixTimestamp;
use tokio::select;
use tokio::signal::unix::{signal, SignalKind};
use tokio::sync::broadcast::{Receiver, Sender};
use tracing::info;
#[derive(Clone, Serialize, Deserialize)]
pub struct QueueItem {
pub numbers: Vec<u64>,
pub programs: Vec<String>
}
#[derive(Clone, Serialize, Deserialize)]
pub struct Block {
pub epoch: u32,
pub previous_hash: String,
pub producer: String,
pub hash: String,
pub parent_number: u64,
pub number: u64,
pub number_of_transactions: u32,
pub successful_transactions: u32,
pub vote_transactions: u32,
pub total_tx_fees: u64,
pub number_of_rewards: u32,
pub total_reward_amount: u64,
pub total_compute_units_consumed: u64,
pub total_compute_units_limit: u64,
pub block_time: u64,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct Transfer {
pub transaction_hash: String,
pub status: u16,
pub source: String,
pub source_association: Option<String>,
pub destination: String,
pub destination_association: Option<String>,
pub token: Option<String>,
pub amount: i128,
pub timestamp: u64,
}
#[derive(Clone, Deserialize, Serialize)]
pub struct TransactionInfo {
pub hash: String,
pub status: u16,
pub fee: u64,
pub total_cu_consumed: u64,
pub program_consumptions: Vec<ProgramConsumption>,
pub transfers: Vec<Transfer>,
}
#[derive(Clone, Deserialize, Serialize)]
pub struct ProgramConsumption {
pub tx: String,
pub status: u16,
pub line: u32,
pub program: String,
pub cu_consumed: u64,
pub cu_limit: u64,
pub timestamp: UnixTimestamp,
}
#[derive(Debug)]
pub struct Shutdown {
shutdown: bool,
notify: Receiver<()>,
}
impl Shutdown {
pub fn new(notify: Receiver<()>) -> Shutdown {
Shutdown {
shutdown: false,
notify,
}
}
pub fn is_shutdown(&self) -> bool {
self.shutdown
}
pub fn shutdown(&mut self) {
self.shutdown = true;
}
pub async fn recv(&mut self) {
if self.is_shutdown() {
return;
}
let _ = self.notify.recv().await;
self.shutdown();
}
pub async fn watchdog(&mut self, notifier: Sender<()>) {
let mut alarm_sig = signal(SignalKind::alarm()).expect("Alarm stream failed.");
let mut hangup_sig = signal(SignalKind::hangup()).expect("Hangup stream failed.");
let mut int_sig = signal(SignalKind::interrupt()).expect("Interrupt stream failed.");
let mut quit_sig = signal(SignalKind::quit()).expect("Quit stream failed.");
let mut term_sig = signal(SignalKind::terminate()).expect("Terminate stream failed.");
select! {
_ = alarm_sig.recv() => {
info!("SIGALRM received, terminating now!");
}
_ = hangup_sig.recv() => {
info!("SIGHUP received, terminating now!");
}
_ = int_sig.recv() => {
info!("SIGINT received, terminating now!");
}
_ = quit_sig.recv() => {
info!("SIGQUIT received, terminating now!");
}
_ = term_sig.recv() => {
info!("SIGTERM received, terminating now!");
}
}
self.shutdown = true;
drop(notifier);
}
}