]>
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; | |
74 | alert.nExpiration = GetTime() + 365 * 60 * 60; | |
7af996b2 | 75 | alert.nID = 1000; // use https://github.com/zcash/zcash/wiki/specification#assigned-numbers to keep track of alert IDs |
2513363e S |
76 | alert.nCancel = 0; // cancels previous messages up to this ID number |
77 | ||
78 | // These versions are protocol versions | |
656a5f0b | 79 | // 70002 : 0.11.2.* |
2513363e S |
80 | alert.nMinVer = 70002; |
81 | alert.nMaxVer = 70002; | |
82 | ||
83 | // | |
84 | // main.cpp: | |
85 | // 1000 for Misc warnings like out of disk space and clock is wrong | |
86 | // 2000 for longer invalid proof-of-work chain | |
87 | // Higher numbers mean higher priority | |
a40034f7 | 88 | // 4000 or higher will put the RPC into safe mode |
2513363e S |
89 | alert.nPriority = 5000; |
90 | alert.strComment = ""; | |
b39e1bdb | 91 | alert.strStatusBar = "URGENT: Upgrade required: see https://z.cash"; |
a40034f7 | 92 | alert.strRPCError = "URGENT: Upgrade required: see https://z.cash"; |
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/")); |
2513363e S |
96 | |
97 | // Sign | |
b39e1bdb S |
98 | const CChainParams& chainparams = Params(); |
99 | std::string networkID = chainparams.NetworkIDString(); | |
100 | bool fIsTestNet = networkID.compare("test") == 0; | |
101 | std::vector<unsigned char> vchTmp(ParseHex(fIsTestNet ? pszTestNetPrivKey : pszPrivKey)); | |
2513363e S |
102 | CPrivKey vchPrivKey(vchTmp.begin(), vchTmp.end()); |
103 | ||
104 | CDataStream sMsg(SER_NETWORK, CLIENT_VERSION); | |
105 | sMsg << *(CUnsignedAlert*)&alert; | |
106 | alert.vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end()); | |
107 | CKey key; | |
108 | if (!key.SetPrivKey(vchPrivKey, false)) | |
109 | { | |
110 | printf("ThreadSendAlert() : key.SetPrivKey failed\n"); | |
111 | return; | |
112 | } | |
113 | if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig)) | |
114 | { | |
115 | printf("ThreadSendAlert() : key.Sign failed\n"); | |
116 | return; | |
117 | } | |
118 | ||
119 | // Test | |
120 | CDataStream sBuffer(SER_NETWORK, CLIENT_VERSION); | |
121 | sBuffer << alert; | |
122 | CAlert alert2; | |
123 | sBuffer >> alert2; | |
b39e1bdb | 124 | if (!alert2.CheckSignature(chainparams.AlertKey())) |
2513363e S |
125 | { |
126 | printf("ThreadSendAlert() : CheckSignature failed\n"); | |
127 | return; | |
128 | } | |
129 | assert(alert2.vchMsg == alert.vchMsg); | |
130 | assert(alert2.vchSig == alert.vchSig); | |
131 | alert.SetNull(); | |
132 | printf("\nThreadSendAlert:\n"); | |
133 | printf("hash=%s\n", alert2.GetHash().ToString().c_str()); | |
b39e1bdb | 134 | printf("%s\n", alert2.ToString().c_str()); |
2513363e S |
135 | printf("vchMsg=%s\n", HexStr(alert2.vchMsg).c_str()); |
136 | printf("vchSig=%s\n", HexStr(alert2.vchSig).c_str()); | |
137 | ||
138 | // Confirm | |
139 | if (!mapArgs.count("-sendalert")) | |
140 | return; | |
141 | while (vNodes.size() < 1 && !ShutdownRequested()) | |
142 | MilliSleep(500); | |
143 | if (ShutdownRequested()) | |
144 | return; | |
9be2f85c | 145 | |
2513363e S |
146 | // Send |
147 | printf("ThreadSendAlert() : Sending alert\n"); | |
148 | int nSent = 0; | |
149 | { | |
150 | LOCK(cs_vNodes); | |
151 | BOOST_FOREACH(CNode* pnode, vNodes) | |
152 | { | |
153 | if (alert2.RelayTo(pnode)) | |
154 | { | |
155 | printf("ThreadSendAlert() : Sent alert to %s\n", pnode->addr.ToString().c_str()); | |
156 | nSent++; | |
157 | } | |
158 | } | |
159 | } | |
160 | printf("ThreadSendAlert() : Alert sent to %d nodes\n", nSent); | |
b39e1bdb | 161 | } |