tree checksum vpatch file split hunks
all signers: mod6
antecedents: rm_rf_upnp
press order: 
| genesis | mod6 | 
| bitcoin-asciilifeform.1 | mod6 | 
| rm_rf_upnp | mod6 | 
| bitcoin-asciilifeform.3-turdmeister-alert-snip | mod6 | 
patch: 
(1720 . 21)(1720 . 11)- 110908F2C5982131591B43888D7F087848746914E5AEBF96E1809219E9C073FCF4665695E3ACFD85ED1AD2126B452749273BC70AF0536A773B08A1D55575012D
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