1 // Copyright (c) 2016 The Zcash developers
2 // Original code from: https://gist.github.com/laanwj/0e689cfa37b52bcbbb44
6 To set up a new alert system
7 ----------------------------
9 Create a new alert key pair:
10 openssl ecparam -name secp256k1 -genkey -param_enc explicit -outform PEM -out data.pem
12 Get the private key in hex:
13 openssl ec -in data.pem -outform DER | tail -c 279 | xxd -p -c 279
15 Get the public key in hex:
16 openssl ec -in data.pem -pubout -outform DER | tail -c 65 | xxd -p -c 65
18 Update the public keys found in chainparams.cpp.
21 To send an alert message
22 ------------------------
24 Copy the private keys into alertkeys.h.
26 Modify the alert parameters, id and message found in this file.
28 Build and run with -sendalert or -printalert.
30 ./zcashd -printtoconsole -sendalert
32 One minute after starting up, the alert will be broadcast. It is then
33 flooded through the network until the nRelayUntil time, and will be
34 active until nExpiration OR the alert is cancelled.
36 If you make a mistake, send another alert with nCancel set to cancel
49 #include "clientversion.h"
50 #include "chainparams.h"
52 #include "alertkeys.h"
55 static const int64_t DAYS = 24 * 60 * 60;
57 void ThreadSendAlert()
59 if (!mapArgs.count("-sendalert") && !mapArgs.count("-printalert"))
62 MilliSleep(60*1000); // Wait a minute so we get connected
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.
73 alert.nRelayUntil = GetTime() + 15 * 60;
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
76 alert.nCancel = 1001; // cancels previous messages up to this ID number
78 // These versions are protocol versions
80 alert.nMinVer = 170002;
81 alert.nMaxVer = 170002;
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
88 // 4000 or higher will put the RPC into safe mode
89 alert.nPriority = 4000;
90 alert.strComment = "";
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).";
92 alert.strRPCError = alert.strStatusBar;
94 // Set specific client version/versions here. If setSubVer is empty, no filtering on subver is done:
95 // alert.setSubVer.insert(std::string("/MagicBean:0.7.2/"));
96 const std::vector<std::string> useragents = {"MagicBean", "BeanStalk", "AppleSeed", "EleosZcash"};
98 BOOST_FOREACH(const std::string& useragent, useragents) {
99 alert.setSubVer.insert(std::string("/"+useragent+":1.0.10/"));
103 assert(alert.strComment.length() <= 65536); // max length in alert.h
104 assert(alert.strStatusBar.length() <= 256);
105 assert(alert.strRPCError.length() <= 256);
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));
112 CPrivKey vchPrivKey(vchTmp.begin(), vchTmp.end());
114 CDataStream sMsg(SER_NETWORK, CLIENT_VERSION);
115 sMsg << *(CUnsignedAlert*)&alert;
116 alert.vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end());
118 if (!key.SetPrivKey(vchPrivKey, false))
120 printf("ThreadSendAlert() : key.SetPrivKey failed\n");
123 if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig))
125 printf("ThreadSendAlert() : key.Sign failed\n");
130 CDataStream sBuffer(SER_NETWORK, CLIENT_VERSION);
134 if (!alert2.CheckSignature(chainparams.AlertKey()))
136 printf("ThreadSendAlert() : CheckSignature failed\n");
139 assert(alert2.vchMsg == alert.vchMsg);
140 assert(alert2.vchSig == alert.vchSig);
142 printf("\nThreadSendAlert:\n");
143 printf("hash=%s\n", alert2.GetHash().ToString().c_str());
144 printf("%s\n", alert2.ToString().c_str());
145 printf("vchMsg=%s\n", HexStr(alert2.vchMsg).c_str());
146 printf("vchSig=%s\n", HexStr(alert2.vchSig).c_str());
149 if (!mapArgs.count("-sendalert"))
151 while (vNodes.size() < 1 && !ShutdownRequested())
153 if (ShutdownRequested())
157 printf("ThreadSendAlert() : Sending alert\n");
161 BOOST_FOREACH(CNode* pnode, vNodes)
163 if (alert2.RelayTo(pnode))
165 printf("ThreadSendAlert() : Sent alert to %s\n", pnode->addr.ToString().c_str());
170 printf("ThreadSendAlert() : Alert sent to %d nodes\n", nSent);