tree checksum vpatch file split hunks
all signers: mircea_popescu trinque asciilifeform ben_vulpes mod6
antecedents: rm_rf_upnp
press order:
patch:
(1720 . 21)(1720 . 11)- 57C05AEA806DFB1E168FDCBF670B99CDCCBBAE072142CB62A946A309E77DE15ABC7661F24F82291A80AE578951FD009BB1560DD4DD756AD17D84E8089089E45B
5
6
7
8
9
10
11
12
13
14
15 //////////////////////////////////////////////////////////////////////////////
16 //
17 // CAlert
18 // Warnings (was: CAlert)
19 //
20
21 map<uint256, CAlert> mapAlerts;
22 CCriticalSection cs_mapAlerts;
23
24 string GetWarnings(string strFor)
25 {
26 int nPriority = 0;
(1757 . 20)(1747 . 6)
28 strStatusBar = strRPC = "WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.";
29 }
30
31 // Alerts
32 CRITICAL_BLOCK(cs_mapAlerts)
33 {
34 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
35 {
36 const CAlert& alert = item.second;
37 if (alert.AppliesToMe() && alert.nPriority > nPriority)
38 {
39 nPriority = alert.nPriority;
40 strStatusBar = alert.strStatusBar;
41 }
42 }
43 }
44
45 if (strFor == "statusbar")
46 return strStatusBar;
47 else if (strFor == "rpc")
(1779 . 59)(1755 . 6)
49 return "error";
50 }
51
52 bool CAlert::ProcessAlert()
53 {
54 if (!CheckSignature())
55 return false;
56 if (!IsInEffect())
57 return false;
58
59 CRITICAL_BLOCK(cs_mapAlerts)
60 {
61 // Cancel previous alerts
62 for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();)
63 {
64 const CAlert& alert = (*mi).second;
65 if (Cancels(alert))
66 {
67 printf("cancelling alert %d\n", alert.nID);
68 mapAlerts.erase(mi++);
69 }
70 else if (!alert.IsInEffect())
71 {
72 printf("expiring alert %d\n", alert.nID);
73 mapAlerts.erase(mi++);
74 }
75 else
76 mi++;
77 }
78
79 // Check if this alert has been cancelled
80 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
81 {
82 const CAlert& alert = item.second;
83 if (alert.Cancels(*this))
84 {
85 printf("alert already cancelled by %d\n", alert.nID);
86 return false;
87 }
88 }
89
90 // Add to mapAlerts
91 mapAlerts.insert(make_pair(GetHash(), *this));
92 }
93
94 printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
95 MainFrameRepaint();
96 return true;
97 }
98
99
100
101
102
103
104
105
106 //////////////////////////////////////////////////////////////////////////////
107 //
(1954 . 11)(1877 . 6)
109 pfrom->PushGetBlocks(pindexBest, uint256(0));
110 }
111
112 // Relay alerts
113 CRITICAL_BLOCK(cs_mapAlerts)
114 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
115 item.second.RelayTo(pfrom);
116
117 pfrom->fSuccessfullyConnected = true;
118
119 printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight);
(2362 . 22)(2280 . 6)
121 }
122
123
124 else if (strCommand == "alert")
125 {
126 CAlert alert;
127 vRecv >> alert;
128
129 if (alert.ProcessAlert())
130 {
131 // Relay
132 pfrom->setKnown.insert(alert.GetHash());
133 CRITICAL_BLOCK(cs_vNodes)
134 BOOST_FOREACH(CNode* pnode, vNodes)
135 alert.RelayTo(pnode);
136 }
137 }
138
139
140 else
141 {
142 // Ignore unknown commands for extensibility
(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