- 110908F2C5982131591B43888D7F087848746914E5AEBF96E1809219E9C073FCF4665695E3ACFD85ED1AD2126B452749273BC70AF0536A773B08A1D55575012D+ 265F35217E2A79155AA98DC832A62F1A24879F70AA594237811392D5F14EC182DE78CABACCF7F9D0AF07504FF4E37F39EA4C4C6DAC7D6D1B8890258AB40C2D33bitcoin/src/main.h(1355 . 211)(1355 . 4)
147 }
148 };
149
150
151
152
153
154
155
156
157
158 //
159 // Alerts are for notifying old versions if they become too obsolete and
160 // need to upgrade. The message is displayed in the status bar.
161 // Alert messages are broadcast as a vector of signed data. Unserializing may
162 // not read the entire buffer if the alert is for a newer version, but older
163 // versions can still relay the original data.
164 //
165 class CUnsignedAlert
166 {
167 public:
168 int nVersion;
169 int64 nRelayUntil; // when newer nodes stop relaying to newer nodes
170 int64 nExpiration;
171 int nID;
172 int nCancel;
173 std::set<int> setCancel;
174 int nMinVer; // lowest version inclusive
175 int nMaxVer; // highest version inclusive
176 std::set<std::string> setSubVer; // empty matches all
177 int nPriority;
178
179 // Actions
180 std::string strComment;
181 std::string strStatusBar;
182 std::string strReserved;
183
184 IMPLEMENT_SERIALIZE
185 (
186 READWRITE(this->nVersion);
187 nVersion = this->nVersion;
188 READWRITE(nRelayUntil);
189 READWRITE(nExpiration);
190 READWRITE(nID);
191 READWRITE(nCancel);
192 READWRITE(setCancel);
193 READWRITE(nMinVer);
194 READWRITE(nMaxVer);
195 READWRITE(setSubVer);
196 READWRITE(nPriority);
197
198 READWRITE(strComment);
199 READWRITE(strStatusBar);
200 READWRITE(strReserved);
201 )
202
203 void SetNull()
204 {
205 nVersion = 1;
206 nRelayUntil = 0;
207 nExpiration = 0;
208 nID = 0;
209 nCancel = 0;
210 setCancel.clear();
211 nMinVer = 0;
212 nMaxVer = 0;
213 setSubVer.clear();
214 nPriority = 0;
215
216 strComment.clear();
217 strStatusBar.clear();
218 strReserved.clear();
219 }
220
221 std::string ToString() const
222 {
223 std::string strSetCancel;
224 BOOST_FOREACH(int n, setCancel)
225 strSetCancel += strprintf("%d ", n);
226 std::string strSetSubVer;
227 BOOST_FOREACH(std::string str, setSubVer)
228 strSetSubVer += "\"" + str + "\" ";
229 return strprintf(
230 "CAlert(\n"
231 " nVersion = %d\n"
232 " nRelayUntil = %"PRI64d"\n"
233 " nExpiration = %"PRI64d"\n"
234 " nID = %d\n"
235 " nCancel = %d\n"
236 " setCancel = %s\n"
237 " nMinVer = %d\n"
238 " nMaxVer = %d\n"
239 " setSubVer = %s\n"
240 " nPriority = %d\n"
241 " strComment = \"%s\"\n"
242 " strStatusBar = \"%s\"\n"
243 ")\n",
244 nVersion,
245 nRelayUntil,
246 nExpiration,
247 nID,
248 nCancel,
249 strSetCancel.c_str(),
250 nMinVer,
251 nMaxVer,
252 strSetSubVer.c_str(),
253 nPriority,
254 strComment.c_str(),
255 strStatusBar.c_str());
256 }
257
258 void print() const
259 {
260 printf("%s", ToString().c_str());
261 }
262 };
263
264 class CAlert : public CUnsignedAlert
265 {
266 public:
267 std::vector<unsigned char> vchMsg;
268 std::vector<unsigned char> vchSig;
269
270 CAlert()
271 {
272 SetNull();
273 }
274
275 IMPLEMENT_SERIALIZE
276 (
277 READWRITE(vchMsg);
278 READWRITE(vchSig);
279 )
280
281 void SetNull()
282 {
283 CUnsignedAlert::SetNull();
284 vchMsg.clear();
285 vchSig.clear();
286 }
287
288 bool IsNull() const
289 {
290 return (nExpiration == 0);
291 }
292
293 uint256 GetHash() const
294 {
295 return SerializeHash(*this);
296 }
297
298 bool IsInEffect() const
299 {
300 return (GetAdjustedTime() < nExpiration);
301 }
302
303 bool Cancels(const CAlert& alert) const
304 {
305 if (!IsInEffect())
306 return false; // this was a no-op before 31403
307 return (alert.nID <= nCancel || setCancel.count(alert.nID));
308 }
309
310 bool AppliesTo(int nVersion, std::string strSubVerIn) const
311 {
312 return (IsInEffect() &&
313 nMinVer <= nVersion && nVersion <= nMaxVer &&
314 (setSubVer.empty() || setSubVer.count(strSubVerIn)));
315 }
316
317 bool AppliesToMe() const
318 {
319 return AppliesTo(VERSION, ::pszSubVer);
320 }
321
322 bool RelayTo(CNode* pnode) const
323 {
324 if (!IsInEffect())
325 return false;
326 // returns true if wasn't already contained in the set
327 if (pnode->setKnown.insert(GetHash()).second)
328 {
329 if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
330 AppliesToMe() ||
331 GetAdjustedTime() < nRelayUntil)
332 {
333 pnode->PushMessage("alert", *this);
334 return true;
335 }
336 }
337 return false;
338 }
339
340 bool CheckSignature()
341 {
342 CKey key;
343 if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
344 return error("CAlert::CheckSignature() : SetPubKey failed");
345 if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
346 return error("CAlert::CheckSignature() : verify signature failed");
347
348 // Now unserialize the data
349 CDataStream sMsg(vchMsg);
350 sMsg >> *(CUnsignedAlert*)this;
351 return true;
352 }
353
354 bool ProcessAlert();
355 };
356
357 #endif