2016-07-15 19:57:55 -07:00
// Copyright (c) 2016 The Zcash developers
// Original code from: https://gist.github.com/laanwj/0e689cfa37b52bcbbb44
/*
To set up a new alert system
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Create a new alert key pair :
openssl ecparam - name secp256k1 - genkey - param_enc explicit - outform PEM - out data . pem
Get the private key in hex :
openssl ec - in data . pem - outform DER | tail - c 279 | xxd - p - c 279
Get the public key in hex :
openssl ec - in data . pem - pubout - outform DER | tail - c 65 | xxd - p - c 65
Update the public keys found in chainparams . cpp .
To send an alert message
- - - - - - - - - - - - - - - - - - - - - - - -
Copy the private keys into alertkeys . h .
2016-07-16 08:12:19 -07:00
Modify the alert parameters , id and message found in this file .
2016-07-15 19:57:55 -07:00
2016-07-16 08:12:19 -07:00
Build and run with - sendalert or - printalert .
2016-07-15 19:57:55 -07:00
. / zcashd - printtoconsole - sendalert
2016-07-16 08:12:19 -07:00
One minute after starting up , the alert will be broadcast . It is then
2016-07-15 18:05:42 -07:00
flooded through the network until the nRelayUntil time , and will be
active until nExpiration OR the alert is cancelled .
2016-07-16 08:12:19 -07:00
If you make a mistake , send another alert with nCancel set to cancel
2016-07-15 18:05:42 -07:00
the bad alert .
2016-07-16 08:12:19 -07:00
2016-07-15 18:05:42 -07:00
*/
2016-07-16 08:12:19 -07:00
2016-07-15 18:05:42 -07:00
# include "main.h"
# include "net.h"
# include "alert.h"
# include "init.h"
2016-07-15 19:57:55 -07:00
# include "util.h"
# include "utiltime.h"
# include "key.h"
# include "clientversion.h"
# include "chainparams.h"
# include "alertkeys.h"
2016-07-15 18:05:42 -07:00
static const int64_t DAYS = 24 * 60 * 60 ;
void ThreadSendAlert ( )
{
if ( ! mapArgs . count ( " -sendalert " ) & & ! mapArgs . count ( " -printalert " ) )
return ;
2016-07-15 19:57:55 -07:00
MilliSleep ( 60 * 1000 ) ; // Wait a minute so we get connected
2016-07-15 18:05:42 -07:00
//
// Alerts are relayed around the network until nRelayUntil, flood
// filling to every node.
// After the relay time is past, new nodes are told about alerts
// when they connect to peers, until either nExpiration or
// the alert is cancelled by a newer alert.
// Nodes never save alerts to disk, they are in-memory-only.
//
CAlert alert ;
alert . nRelayUntil = GetTime ( ) + 15 * 60 ;
2018-06-22 09:07:12 -07:00
alert . nExpiration = GetTime ( ) + 10 * 365 * 24 * 60 * 60 ;
alert . nID = 1005 ; // use https://github.com/zcash/zcash/wiki/specification#assigned-numbers to keep track of alert IDs
alert . nCancel = 1004 ; // cancels previous messages up to this ID number
2016-07-15 18:05:42 -07:00
// These versions are protocol versions
2016-10-26 12:00:43 -07:00
// 170002 : 1.0.0
alert . nMinVer = 170002 ;
2018-06-22 09:07:12 -07:00
alert . nMaxVer = 170004 ;
2016-07-15 18:05:42 -07:00
//
2017-04-24 11:42:12 -07:00
// main.cpp:
2016-07-15 18:05:42 -07:00
// 1000 for Misc warnings like out of disk space and clock is wrong
2017-04-24 11:42:12 -07:00
// 2000 for longer invalid proof-of-work chain
2016-07-15 18:05:42 -07:00
// Higher numbers mean higher priority
2016-09-03 23:25:33 -07:00
// 4000 or higher will put the RPC into safe mode
2017-06-24 11:49:41 -07:00
alert . nPriority = 4000 ;
2016-07-15 18:05:42 -07:00
alert . strComment = " " ;
2018-06-22 09:07:12 -07:00
alert . strStatusBar = " Your client is out of date and incompatible with the Overwinter network upgrade. Please update to a recent version of Zcash (1.1.0 or later). " ;
2017-04-24 11:42:12 -07:00
alert . strRPCError = alert . strStatusBar ;
2016-07-15 18:05:42 -07:00
// Set specific client version/versions here. If setSubVer is empty, no filtering on subver is done:
2016-10-11 17:10:22 -07:00
// alert.setSubVer.insert(std::string("/MagicBean:0.7.2/"));
2018-06-22 09:07:12 -07:00
const std : : vector < std : : string > useragents = { } ; //{"MagicBean", "BeanStalk", "AppleSeed", "EleosZcash"};
2017-04-24 11:42:12 -07:00
BOOST_FOREACH ( const std : : string & useragent , useragents ) {
}
2016-07-15 18:05:42 -07:00
2017-02-10 15:01:46 -08:00
// Sanity check
assert ( alert . strComment . length ( ) < = 65536 ) ; // max length in alert.h
assert ( alert . strStatusBar . length ( ) < = 256 ) ;
assert ( alert . strRPCError . length ( ) < = 256 ) ;
2016-07-15 18:05:42 -07:00
// Sign
2016-07-15 19:57:55 -07:00
const CChainParams & chainparams = Params ( ) ;
std : : string networkID = chainparams . NetworkIDString ( ) ;
bool fIsTestNet = networkID . compare ( " test " ) = = 0 ;
std : : vector < unsigned char > vchTmp ( ParseHex ( fIsTestNet ? pszTestNetPrivKey : pszPrivKey ) ) ;
2016-07-15 18:05:42 -07:00
CPrivKey vchPrivKey ( vchTmp . begin ( ) , vchTmp . end ( ) ) ;
CDataStream sMsg ( SER_NETWORK , CLIENT_VERSION ) ;
sMsg < < * ( CUnsignedAlert * ) & alert ;
alert . vchMsg = std : : vector < unsigned char > ( sMsg . begin ( ) , sMsg . end ( ) ) ;
CKey key ;
if ( ! key . SetPrivKey ( vchPrivKey , false ) )
{
printf ( " ThreadSendAlert() : key.SetPrivKey failed \n " ) ;
return ;
}
if ( ! key . Sign ( Hash ( alert . vchMsg . begin ( ) , alert . vchMsg . end ( ) ) , alert . vchSig ) )
{
printf ( " ThreadSendAlert() : key.Sign failed \n " ) ;
return ;
}
// Test
CDataStream sBuffer ( SER_NETWORK , CLIENT_VERSION ) ;
sBuffer < < alert ;
CAlert alert2 ;
sBuffer > > alert2 ;
2016-07-15 19:57:55 -07:00
if ( ! alert2 . CheckSignature ( chainparams . AlertKey ( ) ) )
2016-07-15 18:05:42 -07:00
{
printf ( " ThreadSendAlert() : CheckSignature failed \n " ) ;
return ;
}
assert ( alert2 . vchMsg = = alert . vchMsg ) ;
assert ( alert2 . vchSig = = alert . vchSig ) ;
alert . SetNull ( ) ;
printf ( " \n ThreadSendAlert: \n " ) ;
printf ( " hash=%s \n " , alert2 . GetHash ( ) . ToString ( ) . c_str ( ) ) ;
2016-07-15 19:57:55 -07:00
printf ( " %s \n " , alert2 . ToString ( ) . c_str ( ) ) ;
2016-07-15 18:05:42 -07:00
printf ( " vchMsg=%s \n " , HexStr ( alert2 . vchMsg ) . c_str ( ) ) ;
printf ( " vchSig=%s \n " , HexStr ( alert2 . vchSig ) . c_str ( ) ) ;
// Confirm
if ( ! mapArgs . count ( " -sendalert " ) )
return ;
while ( vNodes . size ( ) < 1 & & ! ShutdownRequested ( ) )
MilliSleep ( 500 ) ;
if ( ShutdownRequested ( ) )
return ;
2016-07-16 13:18:42 -07:00
2016-07-15 18:05:42 -07:00
// Send
printf ( " ThreadSendAlert() : Sending alert \n " ) ;
int nSent = 0 ;
{
LOCK ( cs_vNodes ) ;
BOOST_FOREACH ( CNode * pnode , vNodes )
{
if ( alert2 . RelayTo ( pnode ) )
{
printf ( " ThreadSendAlert() : Sent alert to %s \n " , pnode - > addr . ToString ( ) . c_str ( ) ) ;
nSent + + ;
}
}
}
printf ( " ThreadSendAlert() : Alert sent to %d nodes \n " , nSent ) ;
2016-07-15 19:57:55 -07:00
}