-
Notifications
You must be signed in to change notification settings - Fork 174
/
active_stake_cache.sql
173 lines (151 loc) · 4.62 KB
/
active_stake_cache.sql
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
--------------------------------------------------------------------------------
-- Pool active stake cache setup
--------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS GREST.POOL_ACTIVE_STAKE_CACHE (
POOL_ID varchar NOT NULL,
EPOCH_NO bigint NOT NULL,
AMOUNT LOVELACE NOT NULL,
PRIMARY KEY (POOL_ID, EPOCH_NO)
);
CREATE TABLE IF NOT EXISTS GREST.EPOCH_ACTIVE_STAKE_CACHE (
EPOCH_NO bigint NOT NULL,
AMOUNT LOVELACE NOT NULL,
PRIMARY KEY (EPOCH_NO)
);
-- For easier updates only:
DROP TRIGGER IF EXISTS POOL_ACTIVE_STAKE_EPOCH_UPDATE_TRIGGER ON PUBLIC.EPOCH_STAKE;
DROP TRIGGER IF EXISTS EPOCH_ACTIVE_STAKE_EPOCH_UPDATE_TRIGGER ON PUBLIC.EPOCH_STAKE;
DROP FUNCTION IF EXISTS GREST.POOL_ACTIVE_STAKE_EPOCH_UPDATE;
DROP FUNCTION IF EXISTS GREST.EPOCH_ACTIVE_STAKE_EPOCH_UPDATE;
/* HELPER FUNCTIONS */
DROP FUNCTION IF EXISTS grest.get_last_active_stake_validated_epoch ();
CREATE FUNCTION grest.get_last_active_stake_validated_epoch ()
RETURNS INTEGER
LANGUAGE plpgsql
AS
$$
BEGIN
RETURN (
SELECT
last_value --coalesce doesn't work if empty set
FROM
grest.control_table
WHERE
key = 'last_active_stake_validated_epoch'
);
END;
$$;
/* POSSIBLE VALIDATION FOR CACHE (COUNTING ENTRIES) INSTEAD OF JUST DB-SYNC PART (EPOCH_STAKE)
DROP FUNCTION IF EXISTS grest.get_last_active_stake_cache_address_count ();
CREATE FUNCTION grest.get_last_active_stake_cache_address_count ()
RETURNS INTEGER
LANGUAGE plpgsql
AS $$
BEGIN
RETURN (
SELECT count(*) from cache...
)
END;
$$;
*/
DROP FUNCTION IF EXISTS grest.active_stake_cache_update_check ();
CREATE FUNCTION grest.active_stake_cache_update_check ()
RETURNS BOOLEAN
LANGUAGE plpgsql
AS
$$
DECLARE
_current_epoch_no integer;
_last_active_stake_validated_epoch text;
BEGIN
SELECT
grest.get_last_active_stake_validated_epoch()
INTO
_last_active_stake_validated_epoch;
SELECT
grest.get_current_epoch()
INTO
_current_epoch_no;
RAISE NOTICE 'Current epoch: %',
_current_epoch_no;
RAISE NOTICE 'Last active stake validated epoch: %',
_last_active_stake_validated_epoch;
IF
_current_epoch_no > COALESCE(_last_active_stake_validated_epoch::integer, 0)
THEN
RETURN TRUE;
END IF;
RETURN FALSE;
END;
$$;
COMMENT ON FUNCTION grest.active_stake_cache_update_check
IS 'Internal function to determine whether active stake cache should be updated';
DROP FUNCTION IF EXISTS grest.active_stake_cache_update (integer);
/* UPDATE FUNCTION */
CREATE FUNCTION grest.active_stake_cache_update (_epoch_no integer)
RETURNS VOID
LANGUAGE plpgsql
AS
$$
DECLARE
_last_pool_active_stake_cache_epoch_no integer;
_last_epoch_active_stake_cache_epoch_no integer;
BEGIN
/* POOL ACTIVE STAKE CACHE */
SELECT
COALESCE(MAX(epoch_no), 0)
FROM
GREST.POOL_ACTIVE_STAKE_CACHE
INTO _last_pool_active_stake_cache_epoch_no;
-- no way to reinsert previous epoch data if it gets corrupted ATM
-- but that should be a manual task anyway
INSERT INTO GREST.POOL_ACTIVE_STAKE_CACHE
SELECT
POOL_HASH.VIEW AS POOL_ID,
EPOCH_STAKE.EPOCH_NO,
SUM(EPOCH_STAKE.AMOUNT) AS AMOUNT
FROM
EPOCH_STAKE
INNER JOIN POOL_HASH ON POOL_HASH.ID = EPOCH_STAKE.POOL_ID
WHERE
EPOCH_STAKE.EPOCH_NO > _last_pool_active_stake_cache_epoch_no -- no need to worry about epoch 0 as no stake then
AND
EPOCH_STAKE.EPOCH_NO <= _epoch_no
GROUP BY
POOL_HASH.VIEW,
EPOCH_STAKE.EPOCH_NO
ON CONFLICT (
POOL_ID,
EPOCH_NO
) DO UPDATE
SET AMOUNT = EXCLUDED.AMOUNT;
/* EPOCH ACTIVE STAKE CACHE */
SELECT
COALESCE(MAX(epoch_no), 0)
FROM
GREST.EPOCH_ACTIVE_STAKE_CACHE
INTO _last_epoch_active_stake_cache_epoch_no;
INSERT INTO GREST.EPOCH_ACTIVE_STAKE_CACHE
SELECT
EPOCH_STAKE.EPOCH_NO,
SUM(EPOCH_STAKE.AMOUNT) AS AMOUNT
FROM
EPOCH_STAKE
WHERE
EPOCH_STAKE.EPOCH_NO > _last_epoch_active_stake_cache_epoch_no -- no need to worry about epoch 0 as no stake then
AND
EPOCH_STAKE.EPOCH_NO <= _epoch_no
GROUP BY
EPOCH_STAKE.EPOCH_NO
ON CONFLICT (
EPOCH_NO
) DO UPDATE
SET AMOUNT = EXCLUDED.AMOUNT;
PERFORM grest.update_control_table(
'last_active_stake_validated_epoch',
_epoch_no::text
);
END;
$$;
COMMENT ON FUNCTION grest.active_stake_cache_update
IS 'Internal function to update active stake cache (both epoch and pool tables).';