From 174a68b3b78e77fbf6cf5e0b42961b4f5fa3327e Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 14 Jul 2016 22:38:41 -0700 Subject: [PATCH 01/10] Use new public/private key pairs for alert system. --- src/chainparams.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 1f5fc2c30..8de90918d 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -54,7 +54,7 @@ public: pchMessageStart[1] = 0xee; pchMessageStart[2] = 0x4e; pchMessageStart[3] = 0xd8; - vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); + vAlertPubKey = ParseHex("04b7ecf0baa90495ceb4e4090f6b2fd37eec1e9c85fac68a487f3ce11589692e4a317479316ee814e066638e1db54e37a10689b70286e6315b1087b6615d179264"); nDefaultPort = 8233; nMinerThreads = 0; nMaxTipAge = 24 * 60 * 60; @@ -149,7 +149,7 @@ public: pchMessageStart[1] = 0xf0; pchMessageStart[2] = 0x94; pchMessageStart[3] = 0x11; - vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"); + vAlertPubKey = ParseHex("044e7a1553392325c871c5ace5d6ad73501c66f4c185d6b0453cf45dec5a1322e705c672ac1a27ef7cdaf588c10effdf50ed5f95f85f2f54a5f6159fca394ed0c6"); nDefaultPort = 18233; nMinerThreads = 0; nMaxTipAge = 0x7fffffff; From 2513363e81aa3586da85a0ffb880e80761a8823e Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 15 Jul 2016 18:05:42 -0700 Subject: [PATCH 02/10] Add sendalert.cpp to repo. --- src/sendalert.cpp | 157 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 src/sendalert.cpp diff --git a/src/sendalert.cpp b/src/sendalert.cpp new file mode 100644 index 000000000..610c1aedd --- /dev/null +++ b/src/sendalert.cpp @@ -0,0 +1,157 @@ +/* +So you need to broadcast an alert... +... here's what to do: + +1. Copy sendalert.cpp into your bitcoind build directory + +2. Decrypt the alert keys + copy the decrypted file as alertkeys.h into the src/ directory. + +3. Modify the alert parameters in sendalert.cpp + See the comments in the code for what does what. + +4. Add sendalert.cpp to the src/Makefile.am so it gets built: + + libbitcoin_server_a_SOURCES = \ + sendalert.cpp \ + ... etc + +5. Update init.cpp to launch the send alert thread. + Define the thread function as external at the top of init.cpp: + + extern void ThreadSendAlert(); + + Add this call at the end of AppInit2: + + threadGroup.create_thread(boost::bind(ThreadSendAlert)); + +6. build bitcoind, then run it with -printalert or -sendalert + I usually run it like this: + ./bitcoind -printtoconsole -sendalert + +One minute after starting up the alert will be broadcast. It is then +flooded through the network until the nRelayUntil time, and will be +active until nExpiration OR the alert is cancelled. + +If you screw up something, send another alert with nCancel set to cancel +the bad alert. +*/ +#include "main.h" +#include "net.h" +#include "alert.h" +#include "init.h" + +static const int64_t DAYS = 24 * 60 * 60; + +void ThreadSendAlert() +{ + MilliSleep(60*1000); // Wait a minute so we get connected + if (!mapArgs.count("-sendalert") && !mapArgs.count("-printalert")) + return; + + // + // 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; + alert.nExpiration = GetTime() + 365 * 60 * 60; + alert.nID = 1040; // use https://en.bitcoin.it/wiki/Alerts to keep track of alert IDs + alert.nCancel = 0; // cancels previous messages up to this ID number + + // These versions are protocol versions + // 60002 : 0.7.* + // 70001 : 0.8.* + // 70002 : 0.9.* + alert.nMinVer = 70002; + alert.nMaxVer = 70002; + + // + // main.cpp: + // 1000 for Misc warnings like out of disk space and clock is wrong + // 2000 for longer invalid proof-of-work chain + // Higher numbers mean higher priority + alert.nPriority = 5000; + alert.strComment = ""; + alert.strStatusBar = "URGENT: Upgrade required: see https://www.bitcoin.org/heartbleed"; + + // Set specific client version/versions here. If setSubVer is empty, no filtering on subver is done: + // alert.setSubVer.insert(std::string("/Satoshi:0.7.2/")); + + // Sign +#include "alertkeys.h" + + std::vector vchTmp(ParseHex(TestNet() ? pszTestNetPrivKey : pszPrivKey)); + CPrivKey vchPrivKey(vchTmp.begin(), vchTmp.end()); + + CDataStream sMsg(SER_NETWORK, CLIENT_VERSION); + sMsg << *(CUnsignedAlert*)&alert; + alert.vchMsg = std::vector(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; + if (!alert2.CheckSignature()) + { + printf("ThreadSendAlert() : CheckSignature failed\n"); + return; + } + assert(alert2.vchMsg == alert.vchMsg); + assert(alert2.vchSig == alert.vchSig); + alert.SetNull(); + printf("\nThreadSendAlert:\n"); + printf("hash=%s\n", alert2.GetHash().ToString().c_str()); + alert2.print(); + 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; +#ifdef QT_GUI + if (ThreadSafeMessageBox("Send alert?", "ThreadSendAlert", wxYES_NO | wxNO_DEFAULT) != wxYES) + return; + if (ThreadSafeMessageBox("Send alert, are you sure?", "ThreadSendAlert", wxYES_NO | wxNO_DEFAULT) != wxYES) + { + ThreadSafeMessageBox("Nothing sent", "ThreadSendAlert", wxOK); + return; + } +#endif + + // 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); +} \ No newline at end of file From b39e1bdbcaf4b9db2f562f874390d289e90b3155 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 15 Jul 2016 19:57:55 -0700 Subject: [PATCH 03/10] Fixes to integrate sendalert.cpp. Add sendalert.cpp to build process. Add alertkeys.h as a placeholder for private keys. --- src/Makefile.am | 1 + src/alertkeys.h | 10 ++++++++ src/init.cpp | 5 ++++ src/sendalert.cpp | 60 ++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 src/alertkeys.h diff --git a/src/Makefile.am b/src/Makefile.am index f4613c27c..d02e09563 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -189,6 +189,7 @@ libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h # server: shared between bitcoind and bitcoin-qt libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) libbitcoin_server_a_SOURCES = \ + sendalert.cpp \ addrman.cpp \ alert.cpp \ bloom.cpp \ diff --git a/src/alertkeys.h b/src/alertkeys.h new file mode 100644 index 000000000..32d26638e --- /dev/null +++ b/src/alertkeys.h @@ -0,0 +1,10 @@ +#ifndef BITCOIN_ALERTKEYS_H +#define BITCOIN_ALERTKEYS_H + +// REMINDER: DO NOT COMMIT YOUR PRIVATE KEYS TO THE GIT REPOSITORY! + +const char* pszPrivKey = "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; +const char* pszTestNetPrivKey = "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + +#endif + diff --git a/src/init.cpp b/src/init.cpp index f8183ace8..b9d75a8d5 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -52,6 +52,8 @@ using namespace std; +extern void ThreadSendAlert(); + ZCJoinSplit* pzcashParams = NULL; #ifdef ENABLE_WALLET @@ -1491,5 +1493,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } #endif + // SENDALERT + threadGroup.create_thread(boost::bind(ThreadSendAlert)); + return !fRequestShutdown; } diff --git a/src/sendalert.cpp b/src/sendalert.cpp index 610c1aedd..29d353ba9 100644 --- a/src/sendalert.cpp +++ b/src/sendalert.cpp @@ -1,3 +1,36 @@ +// 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. + +Modify the alert parameters and message found in this file. + +Build and run to send the alert (after 60 seconds): + +./zcashd -printtoconsole -sendalert + +*/ + /* So you need to broadcast an alert... ... here's what to do: @@ -41,14 +74,24 @@ the bad alert. #include "alert.h" #include "init.h" +#include "util.h" +#include "utiltime.h" +#include "key.h" +#include "clientversion.h" +#include "chainparams.h" + +#include "alertkeys.h" + + static const int64_t DAYS = 24 * 60 * 60; void ThreadSendAlert() { - MilliSleep(60*1000); // Wait a minute so we get connected if (!mapArgs.count("-sendalert") && !mapArgs.count("-printalert")) return; + MilliSleep(60*1000); // Wait a minute so we get connected + // // Alerts are relayed around the network until nRelayUntil, flood // filling to every node. @@ -77,15 +120,16 @@ void ThreadSendAlert() // Higher numbers mean higher priority alert.nPriority = 5000; alert.strComment = ""; - alert.strStatusBar = "URGENT: Upgrade required: see https://www.bitcoin.org/heartbleed"; + alert.strStatusBar = "URGENT: Upgrade required: see https://z.cash"; // Set specific client version/versions here. If setSubVer is empty, no filtering on subver is done: // alert.setSubVer.insert(std::string("/Satoshi:0.7.2/")); // Sign -#include "alertkeys.h" - - std::vector vchTmp(ParseHex(TestNet() ? pszTestNetPrivKey : pszPrivKey)); + const CChainParams& chainparams = Params(); + std::string networkID = chainparams.NetworkIDString(); + bool fIsTestNet = networkID.compare("test") == 0; + std::vector vchTmp(ParseHex(fIsTestNet ? pszTestNetPrivKey : pszPrivKey)); CPrivKey vchPrivKey(vchTmp.begin(), vchTmp.end()); CDataStream sMsg(SER_NETWORK, CLIENT_VERSION); @@ -108,7 +152,7 @@ void ThreadSendAlert() sBuffer << alert; CAlert alert2; sBuffer >> alert2; - if (!alert2.CheckSignature()) + if (!alert2.CheckSignature(chainparams.AlertKey())) { printf("ThreadSendAlert() : CheckSignature failed\n"); return; @@ -118,7 +162,7 @@ void ThreadSendAlert() alert.SetNull(); printf("\nThreadSendAlert:\n"); printf("hash=%s\n", alert2.GetHash().ToString().c_str()); - alert2.print(); + printf("%s\n", alert2.ToString().c_str()); printf("vchMsg=%s\n", HexStr(alert2.vchMsg).c_str()); printf("vchSig=%s\n", HexStr(alert2.vchSig).c_str()); @@ -154,4 +198,4 @@ void ThreadSendAlert() } } printf("ThreadSendAlert() : Alert sent to %d nodes\n", nSent); -} \ No newline at end of file +} From acefacf1b93b183762fe8570c18e454cae73bd7f Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 16 Jul 2016 08:03:36 -0700 Subject: [PATCH 04/10] Disable QT alert message. --- src/sendalert.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sendalert.cpp b/src/sendalert.cpp index 29d353ba9..deb42a9a2 100644 --- a/src/sendalert.cpp +++ b/src/sendalert.cpp @@ -173,6 +173,7 @@ void ThreadSendAlert() MilliSleep(500); if (ShutdownRequested()) return; +#if 0 #ifdef QT_GUI if (ThreadSafeMessageBox("Send alert?", "ThreadSendAlert", wxYES_NO | wxNO_DEFAULT) != wxYES) return; @@ -182,7 +183,7 @@ void ThreadSendAlert() return; } #endif - +#endif // Send printf("ThreadSendAlert() : Sending alert\n"); int nSent = 0; From 8e77a067efffe1efa68aec8ae327cac70d940bea Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 16 Jul 2016 08:12:19 -0700 Subject: [PATCH 05/10] Update comments. --- src/sendalert.cpp | 43 ++++++------------------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/src/sendalert.cpp b/src/sendalert.cpp index deb42a9a2..c4aa6a814 100644 --- a/src/sendalert.cpp +++ b/src/sendalert.cpp @@ -23,52 +23,21 @@ To send an alert message Copy the private keys into alertkeys.h. -Modify the alert parameters and message found in this file. +Modify the alert parameters, id and message found in this file. -Build and run to send the alert (after 60 seconds): +Build and run with -sendalert or -printalert. ./zcashd -printtoconsole -sendalert -*/ - -/* -So you need to broadcast an alert... -... here's what to do: - -1. Copy sendalert.cpp into your bitcoind build directory - -2. Decrypt the alert keys - copy the decrypted file as alertkeys.h into the src/ directory. - -3. Modify the alert parameters in sendalert.cpp - See the comments in the code for what does what. - -4. Add sendalert.cpp to the src/Makefile.am so it gets built: - - libbitcoin_server_a_SOURCES = \ - sendalert.cpp \ - ... etc - -5. Update init.cpp to launch the send alert thread. - Define the thread function as external at the top of init.cpp: - - extern void ThreadSendAlert(); - - Add this call at the end of AppInit2: - - threadGroup.create_thread(boost::bind(ThreadSendAlert)); - -6. build bitcoind, then run it with -printalert or -sendalert - I usually run it like this: - ./bitcoind -printtoconsole -sendalert - -One minute after starting up the alert will be broadcast. It is then +One minute after starting up, the alert will be broadcast. It is then flooded through the network until the nRelayUntil time, and will be active until nExpiration OR the alert is cancelled. -If you screw up something, send another alert with nCancel set to cancel +If you make a mistake, send another alert with nCancel set to cancel the bad alert. + */ + #include "main.h" #include "net.h" #include "alert.h" From 2e6f1f8de9044519a6c2181efad24f25ada39cce Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 16 Jul 2016 08:17:56 -0700 Subject: [PATCH 06/10] Update alert ID start value and URL in comment. --- src/sendalert.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sendalert.cpp b/src/sendalert.cpp index c4aa6a814..6882e7980 100644 --- a/src/sendalert.cpp +++ b/src/sendalert.cpp @@ -72,7 +72,7 @@ void ThreadSendAlert() CAlert alert; alert.nRelayUntil = GetTime() + 15 * 60; alert.nExpiration = GetTime() + 365 * 60 * 60; - alert.nID = 1040; // use https://en.bitcoin.it/wiki/Alerts to keep track of alert IDs + alert.nID = 1000; // use https://z.cash to keep track of alert IDs alert.nCancel = 0; // cancels previous messages up to this ID number // These versions are protocol versions From 656a5f0b6fdc3f815796ddb1f03fb1e65cc6aefe Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 16 Jul 2016 08:18:58 -0700 Subject: [PATCH 07/10] Update alert protocol version comment. --- src/sendalert.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/sendalert.cpp b/src/sendalert.cpp index 6882e7980..c96558ae0 100644 --- a/src/sendalert.cpp +++ b/src/sendalert.cpp @@ -76,9 +76,7 @@ void ThreadSendAlert() alert.nCancel = 0; // cancels previous messages up to this ID number // These versions are protocol versions - // 60002 : 0.7.* - // 70001 : 0.8.* - // 70002 : 0.9.* + // 70002 : 0.11.2.* alert.nMinVer = 70002; alert.nMaxVer = 70002; From 7af996b263dda1c0e28ab29f9c8fc7ab348605c3 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 16 Jul 2016 13:17:47 -0700 Subject: [PATCH 08/10] Update URL for zcash alert IDs. --- src/sendalert.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sendalert.cpp b/src/sendalert.cpp index c96558ae0..32c907844 100644 --- a/src/sendalert.cpp +++ b/src/sendalert.cpp @@ -72,7 +72,7 @@ void ThreadSendAlert() CAlert alert; alert.nRelayUntil = GetTime() + 15 * 60; alert.nExpiration = GetTime() + 365 * 60 * 60; - alert.nID = 1000; // use https://z.cash to keep track of alert IDs + alert.nID = 1000; // use https://github.com/zcash/zcash/wiki/specification#assigned-numbers to keep track of alert IDs alert.nCancel = 0; // cancels previous messages up to this ID number // These versions are protocol versions From 9be2f85c222c2f7d69d200c1157af782db5d54fc Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 16 Jul 2016 13:18:42 -0700 Subject: [PATCH 09/10] Remove QT alert message box. --- src/sendalert.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/sendalert.cpp b/src/sendalert.cpp index 32c907844..d68b38f9e 100644 --- a/src/sendalert.cpp +++ b/src/sendalert.cpp @@ -140,17 +140,7 @@ void ThreadSendAlert() MilliSleep(500); if (ShutdownRequested()) return; -#if 0 -#ifdef QT_GUI - if (ThreadSafeMessageBox("Send alert?", "ThreadSendAlert", wxYES_NO | wxNO_DEFAULT) != wxYES) - return; - if (ThreadSafeMessageBox("Send alert, are you sure?", "ThreadSendAlert", wxYES_NO | wxNO_DEFAULT) != wxYES) - { - ThreadSafeMessageBox("Nothing sent", "ThreadSendAlert", wxOK); - return; - } -#endif -#endif + // Send printf("ThreadSendAlert() : Sending alert\n"); int nSent = 0; From 939aaeb6208d0bbdf115f95799dd5b1271f386a1 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 17 Jul 2016 12:36:26 -0700 Subject: [PATCH 10/10] New alert test data generated for new alert key pair. Added test fixture to create new test data. Added instructions for developer. --- src/test/alert_tests.cpp | 178 ++++++++++++++++++++++++++++++++--- src/test/data/alertTests.raw | Bin 1279 -> 1280 bytes 2 files changed, 163 insertions(+), 15 deletions(-) diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index daaec13ed..ccfb6132b 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -26,62 +26,208 @@ #include #include -#if 0 -// -// alertTests contains 7 alerts, generated with this code: -// (SignAndSave code not shown, alert signing key is secret) -// +#include "key.h" +#include "alertkeys.h" +#include + +/* + * If the alert key pairs have changed, the test suite will fail as the + * test data is now invalid. To create valid test data, signed with a + * new alert private key, follow these steps: + * + * 1. Copy your private key into alertkeys.h. Don't commit this file! + * See sendalert.cpp for more info. + * + * 2. Set the GENERATE_ALERTS_FLAG to true. + * + * 3. Build and run: + * test_bitcoin -t Generate_Alert_Test_Data + * + * 4. Test data is saved in your current directory as alertTests.raw.NEW + * Copy this file to: src/test/data/alertTests.raw + * + * For debugging purposes, terminal output can be copied into: + * src/test/data/alertTests.raw.h + * + * 5. Clean up... + * - Set GENERATE_ALERTS_FLAG back to false. + * - Remove your private key from alertkeys.h + * + * 6. Build and verify the new test data: + * test_bitcoin -t Alert_tests + * + */ +#define GENERATE_ALERTS_FLAG false + +#if GENERATE_ALERTS_FLAG + +// NOTE: +// A function SignAndSave() was used by Bitcoin Core to create alert test data +// but it has not been made publicly available. So instead, we have adapted +// some publicly available code which achieves the intended result: +// https://gist.github.com/lukem512/9b272bd35e2cdefbf386 + + +// Code to output a C-style array of values +template +std::string HexStrArray(const T itbegin, const T itend, int lineLength) { + std::string rv; + static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + rv.reserve((itend-itbegin)*3); + int i = 0; + for(T it = itbegin; it < itend; ++it) + { + unsigned char val = (unsigned char)(*it); + if(it != itbegin) + { + if (i % lineLength == 0) + rv.push_back('\n'); + else + rv.push_back(' '); + } + rv.push_back('0'); + rv.push_back('x'); + rv.push_back(hexmap[val>>4]); + rv.push_back(hexmap[val&15]); + rv.push_back(','); + i++; + } + + return rv; +} + +template +inline std::string HexStrArray(const T& vch, int lineLength) +{ + return HexStrArray(vch.begin(), vch.end(), lineLength); +} + + +// Sign CAlert with alert private key +bool SignAlert(CAlert &alert) +{ + // serialize alert data + CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); + sMsg << *(CUnsignedAlert*)&alert; + alert.vchMsg = std::vector(sMsg.begin(), sMsg.end()); + + // sign alert + std::vector vchTmp(ParseHex(pszPrivKey)); + CPrivKey vchPrivKey(vchTmp.begin(), vchTmp.end()); + CKey key; + if (!key.SetPrivKey(vchPrivKey, false)) + { + printf("key.SetPrivKey failed\n"); + return false; + } + if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig)) + { + printf("SignAlert() : key.Sign failed\n"); + return false; + } + return true; +} + +// Sign a CAlert and serialize it +bool SignAndSerialize(CAlert &alert, CDataStream &buffer) +{ + // Sign + if(!SignAlert(alert)) + { + printf("SignAndSerialize() : could not sign alert\n"); + return false; + } + // ...and save! + buffer << alert; + return true; +} + +void GenerateAlertTests() +{ + CDataStream sBuffer(SER_DISK, CLIENT_VERSION); + CAlert alert; alert.nRelayUntil = 60; alert.nExpiration = 24 * 60 * 60; alert.nID = 1; - alert.nCancel = 0; // cancels previous messages up to this ID number + alert.nCancel = 0; // cancels previous messages up to this ID number alert.nMinVer = 0; // These versions are protocol versions alert.nMaxVer = 999001; alert.nPriority = 1; alert.strComment = "Alert comment"; alert.strStatusBar = "Alert 1"; - SignAndSave(alert, "test/alertTests"); + // Replace SignAndSave with SignAndSerialize + SignAndSerialize(alert, sBuffer); + // More tests go here ... alert.setSubVer.insert(std::string("/Satoshi:0.1.0/")); alert.strStatusBar = "Alert 1 for Satoshi 0.1.0"; - SignAndSave(alert, "test/alertTests"); + SignAndSerialize(alert, sBuffer); alert.setSubVer.insert(std::string("/Satoshi:0.2.0/")); alert.strStatusBar = "Alert 1 for Satoshi 0.1.0, 0.2.0"; - SignAndSave(alert, "test/alertTests"); + SignAndSerialize(alert, sBuffer); alert.setSubVer.clear(); ++alert.nID; alert.nCancel = 1; alert.nPriority = 100; alert.strStatusBar = "Alert 2, cancels 1"; - SignAndSave(alert, "test/alertTests"); + SignAndSerialize(alert, sBuffer); alert.nExpiration += 60; ++alert.nID; - SignAndSave(alert, "test/alertTests"); + SignAndSerialize(alert, sBuffer); ++alert.nID; alert.nMinVer = 11; alert.nMaxVer = 22; - SignAndSave(alert, "test/alertTests"); + SignAndSerialize(alert, sBuffer); ++alert.nID; alert.strStatusBar = "Alert 2 for Satoshi 0.1.0"; alert.setSubVer.insert(std::string("/Satoshi:0.1.0/")); - SignAndSave(alert, "test/alertTests"); + SignAndSerialize(alert, sBuffer); ++alert.nID; alert.nMinVer = 0; alert.nMaxVer = 999999; alert.strStatusBar = "Evil Alert'; /bin/ls; echo '"; alert.setSubVer.clear(); - SignAndSave(alert, "test/alertTests"); + bool b = SignAndSerialize(alert, sBuffer); + + if (b) { + // Print the hex array, which will become the contents of alertTest.raw.h + std::vector vch = std::vector(sBuffer.begin(), sBuffer.end()); + printf("%s\n", HexStrArray(vch, 8).c_str()); + + // Write the data to alertTests.raw.NEW, to be copied to src/test/data/alertTests.raw + std::ofstream outfile("alertTests.raw.NEW", std::ios::out | std::ios::binary); + outfile.write((const char*)&vch[0], vch.size()); + outfile.close(); + } } -#endif + + + +struct GenerateAlertTestsFixture : public TestingSetup { + GenerateAlertTestsFixture() {} + ~GenerateAlertTestsFixture() {} +}; + +BOOST_FIXTURE_TEST_SUITE(Generate_Alert_Test_Data, GenerateAlertTestsFixture); +BOOST_AUTO_TEST_CASE(GenerateTheAlertTests) +{ + GenerateAlertTests(); +} +BOOST_AUTO_TEST_SUITE_END() + + +#else + struct ReadAlerts : public TestingSetup { @@ -255,3 +401,5 @@ BOOST_AUTO_TEST_CASE(PartitionAlert) } BOOST_AUTO_TEST_SUITE_END() + +#endif diff --git a/src/test/data/alertTests.raw b/src/test/data/alertTests.raw index 01f50680b95aa307a1a013b643ded4ae0bc47162..019f2b0df7b1ce6d483dff6d22a148970c652d26 100644 GIT binary patch delta 607 zcmV-l0-*i>34jWaNJG)Af1qUj_*g=5VAQ*Ax@)#gBRt_1y}+gYE94` zn2TX}pMFiofATx&%8qg{Kye#vm z&%g43J2xi1Hl#ikv~}#_8nB&M{Y;So6q5`BI7mk@MFJrJu;W7e)*A4BVEC`3NHYwFBatzVFoTmI z0~M2?0zN|hgf6G!(y%cSQY!6D zL;@gpEOmcwys%z}z!lI-MfXVM0P3&7P6&gZRSeK$H9FY>Ab34T7eq9>%Ei3rpT)>q zz delta 601 zcmV-f0;c_d3jYa^NJE8;b+;Sx;MM_n_qSI=uI_T@JBiVZ&z}$vcMWoWe#rtLFO`Ad zW4{DI=!mp$?Qe4j;D6mVK$hFIGC*=!|EhP8W03(Rk+4HU8rjpv4@oAeKBfWp>hRUU zTi*EpwpJ1qLE8F6z6nZ<0w4_=TsqWmy68o&hhF(s)zAz*X!{ySP&)qFaOgN1tG9ZQ z0VR`L0a`;Z8YGKV6rm1(kto%O`B6l~8)aUp@Um`BbuD&(`ATf^=g87GZ(T&>t zjU1NZDX5|vVZWm)ebMJ7*F~UCHcXKL6q5`BI7db>L;@f#*Rq=*q!kH8@OG&`dnyHy zemm`c1i!uG*D+PovaX~8AU8w2H$NvsT41Ja^PbA~V7ZWHz0Ctqm^7@&R%H-bCzBxq z6_cR?K0=3;{q|EZ-MQ$8_;$cxXW3%=diB+jEX?@on6wyO(;xyMMh~mW!Ai!fEbt3i zQ6suCpTF6jf3GSzyEz2H)+y87lOY3BLb*4;UE*aml`oG+jA3)t8#ezUM-sC&(S>fF znRu}6<^mv86DIjio&imfTihyRn`96x8FAL!*$D7xp_10|D9eAIQ$P>(A*sE>gwyWSVS