-
Notifications
You must be signed in to change notification settings - Fork 80
Expand file tree
/
Copy pathPartySnapshotManager.sol
More file actions
171 lines (141 loc) · 6.82 KB
/
PartySnapshotManager.sol
File metadata and controls
171 lines (141 loc) · 6.82 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
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
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
// Interface for the main contract to interact with snapshot manager
interface IPoliticalPartyRegistry {
function getPartyStatus(uint256 _partyId) external view returns (uint8);
function getPartyCount() external view returns (uint256);
function getPartyMemberCounts(uint256 _partyId) external view returns (uint256 memberCount, uint256 verifiedMemberCount);
}
contract PartySnapshotManager is Ownable, ReentrancyGuard {
// Data structure for snapshots
struct MembershipSnapshot {
uint256 timestamp;
uint256 blockNumber;
uint256 memberCount;
uint256 verifiedMemberCount;
}
// Storage variables
mapping(uint256 => MembershipSnapshot[]) private _partySnapshots;
uint256 private _lastSnapshotTime;
uint256 private _snapshotRetentionCount = 10;
// Registry contract reference
IPoliticalPartyRegistry public partyRegistry;
// Events
event SnapshotTaken(uint256 indexed timestamp, uint256 indexed blockNumber, uint256 partiesProcessed);
event PartyMembershipSnapshot(uint256 indexed partyId, uint256 indexed snapshotId, uint256 memberCount, uint256 verifiedMemberCount, uint256 timestamp);
event RegistryAddressUpdated(address indexed oldRegistry, address indexed newRegistry);
// Constants
uint8 private constant PARTY_STATUS_ACTIVE = 1;
constructor(address initialOwner, address _partyRegistry) Ownable(initialOwner) {
partyRegistry = IPoliticalPartyRegistry(_partyRegistry);
}
// Update registry address if needed (e.g., if registry is upgraded)
function setRegistryAddress(address _newRegistry) external onlyOwner {
address oldRegistry = address(partyRegistry);
partyRegistry = IPoliticalPartyRegistry(_newRegistry);
emit RegistryAddressUpdated(oldRegistry, _newRegistry);
}
// Set snapshot retention policy
function setSnapshotRetentionCount(uint256 _count) external onlyOwner {
_snapshotRetentionCount = _count;
}
// Take snapshots in batches
function takeSnapshotBatch(uint256 _startPartyId, uint256 _batchSize) external
onlyOwner
nonReentrant
returns (uint256 nextPartyId, uint256 processed)
{
uint256 partyCount = partyRegistry.getPartyCount();
require(_startPartyId < partyCount, "Invalid start ID");
require(_batchSize > 0, "Batch size must be positive");
uint256 currentTime = block.timestamp;
uint256 currentBlock = block.number;
uint256 processedCount = 0;
uint256 i = _startPartyId;
uint256 endId = _startPartyId + _batchSize;
if (endId > partyCount) {
endId = partyCount;
}
for (; i < endId; i++) {
if (partyRegistry.getPartyStatus(i) == PARTY_STATUS_ACTIVE) {
(uint256 memberCount, uint256 verifiedMemberCount) = partyRegistry.getPartyMemberCounts(i);
_partySnapshots[i].push(MembershipSnapshot({
timestamp: currentTime,
blockNumber: currentBlock,
memberCount: memberCount,
verifiedMemberCount: verifiedMemberCount
}));
// Manage retention policy
if (_snapshotRetentionCount > 0 && _partySnapshots[i].length > _snapshotRetentionCount) {
uint256 excessCount = _partySnapshots[i].length - _snapshotRetentionCount;
MembershipSnapshot[] memory tempSnapshots = new MembershipSnapshot[](_snapshotRetentionCount);
for (uint256 j = 0; j < _snapshotRetentionCount; j++) {
tempSnapshots[j] = _partySnapshots[i][excessCount + j];
}
delete _partySnapshots[i];
for (uint256 j = 0; j < _snapshotRetentionCount; j++) {
_partySnapshots[i].push(tempSnapshots[j]);
}
}
emit PartyMembershipSnapshot(i, _partySnapshots[i].length - 1, memberCount,
verifiedMemberCount, currentTime);
processedCount++;
}
}
// Update last snapshot time only after complete snapshot
if (i >= partyCount) {
_lastSnapshotTime = currentTime;
emit SnapshotTaken(currentTime, currentBlock, processedCount);
}
return (i < partyCount ? i : 0, processedCount);
}
// View functions for accessing snapshot data
function getLatestPartySnapshot(uint256 _partyId) external view
returns (uint256 timestamp, uint256 blockNumber, uint256 memberCount, uint256 verifiedMemberCount)
{
require(_partySnapshots[_partyId].length > 0, "No snapshots exist for this party");
MembershipSnapshot storage snapshot = _partySnapshots[_partyId][_partySnapshots[_partyId].length - 1];
return (snapshot.timestamp, snapshot.blockNumber, snapshot.memberCount, snapshot.verifiedMemberCount);
}
function getPartySnapshotHistory(
uint256 _partyId,
uint256 _startIndex,
uint256 _count
)
external
view
returns (
uint256[] memory timestamps,
uint256[] memory memberCounts,
uint256[] memory verifiedMemberCounts
)
{
uint256 snapshotCount = _partySnapshots[_partyId].length;
require(snapshotCount > 0, "No snapshots for this party");
require(_startIndex < snapshotCount, "Start index out of range");
uint256 endIndex = _startIndex + _count;
if (endIndex > snapshotCount) {
endIndex = snapshotCount;
}
uint256 resultSize = endIndex - _startIndex;
timestamps = new uint256[](resultSize);
memberCounts = new uint256[](resultSize);
verifiedMemberCounts = new uint256[](resultSize);
for (uint256 i = 0; i < resultSize; i++) {
uint256 index = _startIndex + i;
timestamps[i] = _partySnapshots[_partyId][index].timestamp;
memberCounts[i] = _partySnapshots[_partyId][index].memberCount;
verifiedMemberCounts[i] = _partySnapshots[_partyId][index].verifiedMemberCount;
}
return (timestamps, memberCounts, verifiedMemberCounts);
}
function getSnapshotStatus() external view returns (
uint256 lastSnapshotTime,
uint256 totalParties,
uint256 retentionPolicy
) {
return (_lastSnapshotTime, partyRegistry.getPartyCount(), _snapshotRetentionCount);
}
}