]>
Commit | Line | Data |
---|---|---|
b39e1bdb S |
1 | // Copyright (c) 2016 The Zcash developers |
2 | // Original code from: https://gist.github.com/laanwj/0e689cfa37b52bcbbb44 | |
3 | ||
4 | /* | |
5 | ||
6 | To set up a new alert system | |
7 | ---------------------------- | |
8 | ||
9 | Create a new alert key pair: | |
10 | openssl ecparam -name secp256k1 -genkey -param_enc explicit -outform PEM -out data.pem | |
11 | ||
12 | Get the private key in hex: | |
13 | openssl ec -in data.pem -outform DER | tail -c 279 | xxd -p -c 279 | |
14 | ||
15 | Get the public key in hex: | |
16 | openssl ec -in data.pem -pubout -outform DER | tail -c 65 | xxd -p -c 65 | |
17 | ||
18 | Update the public keys found in chainparams.cpp. | |
19 | ||
20 | ||
21 | To send an alert message | |
22 | ------------------------ | |
23 | ||
24 | Copy the private keys into alertkeys.h. | |
25 | ||
8e77a067 | 26 | Modify the alert parameters, id and message found in this file. |
b39e1bdb | 27 | |
8e77a067 | 28 | Build and run with -sendalert or -printalert. |
b39e1bdb S |
29 | |
30 | ./zcashd -printtoconsole -sendalert | |
31 | ||
8e77a067 | 32 | One minute after starting up, the alert will be broadcast. It is then |
2513363e S |
33 | flooded through the network until the nRelayUntil time, and will be |
34 | active until nExpiration OR the alert is cancelled. | |
35 | ||
8e77a067 | 36 | If you make a mistake, send another alert with nCancel set to cancel |
2513363e | 37 | the bad alert. |
8e77a067 | 38 | |
2513363e | 39 | */ |
8e77a067 | 40 | |
2513363e S |
41 | #include "main.h" |
42 | #include "net.h" | |
43 | #include "alert.h" | |
44 | #include "init.h" | |
45 | ||
b39e1bdb S |
46 | #include "util.h" |
47 | #include "utiltime.h" | |
48 | #include "key.h" | |
49 | #include "clientversion.h" | |
50 | #include "chainparams.h" | |
51 | ||
52 | #include "alertkeys.h" | |
53 | ||
54 | ||
2513363e S |
55 | static const int64_t DAYS = 24 * 60 * 60; |
56 | ||
57 | void ThreadSendAlert() | |
58 | { | |
2513363e S |
59 | if (!mapArgs.count("-sendalert") && !mapArgs.count("-printalert")) |
60 | return; | |
61 | ||
b39e1bdb S |
62 | MilliSleep(60*1000); // Wait a minute so we get connected |
63 | ||
2513363e S |
64 | // |
65 | // Alerts are relayed around the network until nRelayUntil, flood | |
66 | // filling to every node. | |
67 | // After the relay time is past, new nodes are told about alerts | |
68 | // when they connect to peers, until either nExpiration or | |
69 | // the alert is cancelled by a newer alert. | |
70 | // Nodes never save alerts to disk, they are in-memory-only. | |
71 | // | |
72 | CAlert alert; | |
73 | alert.nRelayUntil = GetTime() + 15 * 60; | |
262fc5f4 DH |
74 | alert.nExpiration = GetTime() + 12 * 30 * 24 * 60 * 60; |
75 | alert.nID = 1004; // use https://github.com/zcash/zcash/wiki/specification#assigned-numbers to keep track of alert IDs | |
8d8318c9 | 76 | alert.nCancel = 1001; // cancels previous messages up to this ID number |
2513363e S |
77 | |
78 | // These versions are protocol versions | |
55d4f13b S |
79 | // 170002 : 1.0.0 |
80 | alert.nMinVer = 170002; | |
81 | alert.nMaxVer = 170002; | |
2513363e S |
82 | |
83 | // | |
fa151bc5 | 84 | // main.cpp: |
2513363e | 85 | // 1000 for Misc warnings like out of disk space and clock is wrong |
fa151bc5 | 86 | // 2000 for longer invalid proof-of-work chain |
2513363e | 87 | // Higher numbers mean higher priority |
a40034f7 | 88 | // 4000 or higher will put the RPC into safe mode |
262fc5f4 | 89 | alert.nPriority = 4000; |
2513363e | 90 | alert.strComment = ""; |
262fc5f4 | 91 | alert.strStatusBar = "Your client version 1.0.10 has degraded networking behavior. Please update to the most recent version of Zcash (1.0.10-1 or later)."; |
fa151bc5 | 92 | alert.strRPCError = alert.strStatusBar; |
2513363e S |
93 | |
94 | // Set specific client version/versions here. If setSubVer is empty, no filtering on subver is done: | |
5bd677f5 | 95 | // alert.setSubVer.insert(std::string("/MagicBean:0.7.2/")); |
fa151bc5 DH |
96 | const std::vector<std::string> useragents = {"MagicBean", "BeanStalk", "AppleSeed", "EleosZcash"}; |
97 | ||
98 | BOOST_FOREACH(const std::string& useragent, useragents) { | |
262fc5f4 | 99 | alert.setSubVer.insert(std::string("/"+useragent+":1.0.10/")); |
fa151bc5 | 100 | } |
2513363e | 101 | |
f47269cd S |
102 | // Sanity check |
103 | assert(alert.strComment.length() <= 65536); // max length in alert.h | |
104 | assert(alert.strStatusBar.length() <= 256); | |
105 | assert(alert.strRPCError.length() <= 256); | |
106 | ||
2513363e | 107 | // Sign |
b39e1bdb S |
108 | const CChainParams& chainparams = Params(); |
109 | std::string networkID = chainparams.NetworkIDString(); | |
110 | bool fIsTestNet = networkID.compare("test") == 0; | |
111 | std::vector<unsigned char> vchTmp(ParseHex(fIsTestNet ? pszTestNetPrivKey : pszPrivKey)); | |
2513363e S |
112 | CPrivKey vchPrivKey(vchTmp.begin(), vchTmp.end()); |
113 | ||
114 | CDataStream sMsg(SER_NETWORK, CLIENT_VERSION); | |
115 | sMsg << *(CUnsignedAlert*)&alert; | |
116 | alert.vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end()); | |
117 | CKey key; | |
118 | if (!key.SetPrivKey(vchPrivKey, false)) | |
119 | { | |
120 | printf("ThreadSendAlert() : key.SetPrivKey failed\n"); | |
121 | return; | |
122 | } | |
123 | if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig)) | |
124 | { | |
125 | printf("ThreadSendAlert() : key.Sign failed\n"); | |
126 | return; | |
127 | } | |
128 | ||
129 | // Test | |
130 | CDataStream sBuffer(SER_NETWORK, CLIENT_VERSION); | |
131 | sBuffer << alert; | |
132 | CAlert alert2; | |
133 | sBuffer >> alert2; | |
b39e1bdb | 134 | if (!alert2.CheckSignature(chainparams.AlertKey())) |
2513363e S |
135 | { |
136 | printf("ThreadSendAlert() : CheckSignature failed\n"); | |
137 | return; | |
138 | } | |
139 | assert(alert2.vchMsg == alert.vchMsg); | |
140 | assert(alert2.vchSig == alert.vchSig); | |
141 | alert.SetNull(); | |
142 | printf("\nThreadSendAlert:\n"); | |
143 | printf("hash=%s\n", alert2.GetHash().ToString().c_str()); | |
b39e1bdb | 144 | printf("%s\n", alert2.ToString().c_str()); |
2513363e S |
145 | printf("vchMsg=%s\n", HexStr(alert2.vchMsg).c_str()); |
146 | printf("vchSig=%s\n", HexStr(alert2.vchSig).c_str()); | |
147 | ||
148 | // Confirm | |
149 | if (!mapArgs.count("-sendalert")) | |
150 | return; | |
151 | while (vNodes.size() < 1 && !ShutdownRequested()) | |
152 | MilliSleep(500); | |
153 | if (ShutdownRequested()) | |
154 | return; | |
9be2f85c | 155 | |
2513363e S |
156 | // Send |
157 | printf("ThreadSendAlert() : Sending alert\n"); | |
158 | int nSent = 0; | |
159 | { | |
160 | LOCK(cs_vNodes); | |
161 | BOOST_FOREACH(CNode* pnode, vNodes) | |
162 | { | |
163 | if (alert2.RelayTo(pnode)) | |
164 | { | |
165 | printf("ThreadSendAlert() : Sent alert to %s\n", pnode->addr.ToString().c_str()); | |
166 | nSent++; | |
167 | } | |
168 | } | |
169 | } | |
170 | printf("ThreadSendAlert() : Alert sent to %d nodes\n", nSent); | |
b39e1bdb | 171 | } |