Merge branch 'testnet_alert' of git://github.com/gavinandresen/bitcoin-git
This commit is contained in:
commit
91c218a1cb
10 changed files with 351 additions and 293 deletions
|
@ -119,6 +119,7 @@ HEADERS += src/qt/bitcoingui.h \
|
||||||
src/qt/aboutdialog.h \
|
src/qt/aboutdialog.h \
|
||||||
src/qt/editaddressdialog.h \
|
src/qt/editaddressdialog.h \
|
||||||
src/qt/bitcoinaddressvalidator.h \
|
src/qt/bitcoinaddressvalidator.h \
|
||||||
|
src/alert.h \
|
||||||
src/addrman.h \
|
src/addrman.h \
|
||||||
src/base58.h \
|
src/base58.h \
|
||||||
src/bignum.h \
|
src/bignum.h \
|
||||||
|
@ -189,6 +190,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
|
||||||
src/qt/aboutdialog.cpp \
|
src/qt/aboutdialog.cpp \
|
||||||
src/qt/editaddressdialog.cpp \
|
src/qt/editaddressdialog.cpp \
|
||||||
src/qt/bitcoinaddressvalidator.cpp \
|
src/qt/bitcoinaddressvalidator.cpp \
|
||||||
|
src/alert.cpp \
|
||||||
src/version.cpp \
|
src/version.cpp \
|
||||||
src/sync.cpp \
|
src/sync.cpp \
|
||||||
src/util.cpp \
|
src/util.cpp \
|
||||||
|
|
239
src/alert.cpp
Normal file
239
src/alert.cpp
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
//
|
||||||
|
// Alert system
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "alert.h"
|
||||||
|
#include "key.h"
|
||||||
|
#include "net.h"
|
||||||
|
#include "sync.h"
|
||||||
|
#include "ui_interface.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
map<uint256, CAlert> mapAlerts;
|
||||||
|
CCriticalSection cs_mapAlerts;
|
||||||
|
|
||||||
|
static const char* pszMainKey = "04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284";
|
||||||
|
static const char* pszTestKey = "04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a";
|
||||||
|
|
||||||
|
void CUnsignedAlert::SetNull()
|
||||||
|
{
|
||||||
|
nVersion = 1;
|
||||||
|
nRelayUntil = 0;
|
||||||
|
nExpiration = 0;
|
||||||
|
nID = 0;
|
||||||
|
nCancel = 0;
|
||||||
|
setCancel.clear();
|
||||||
|
nMinVer = 0;
|
||||||
|
nMaxVer = 0;
|
||||||
|
setSubVer.clear();
|
||||||
|
nPriority = 0;
|
||||||
|
|
||||||
|
strComment.clear();
|
||||||
|
strStatusBar.clear();
|
||||||
|
strReserved.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CUnsignedAlert::ToString() const
|
||||||
|
{
|
||||||
|
std::string strSetCancel;
|
||||||
|
BOOST_FOREACH(int n, setCancel)
|
||||||
|
strSetCancel += strprintf("%d ", n);
|
||||||
|
std::string strSetSubVer;
|
||||||
|
BOOST_FOREACH(std::string str, setSubVer)
|
||||||
|
strSetSubVer += "\"" + str + "\" ";
|
||||||
|
return strprintf(
|
||||||
|
"CAlert(\n"
|
||||||
|
" nVersion = %d\n"
|
||||||
|
" nRelayUntil = %"PRI64d"\n"
|
||||||
|
" nExpiration = %"PRI64d"\n"
|
||||||
|
" nID = %d\n"
|
||||||
|
" nCancel = %d\n"
|
||||||
|
" setCancel = %s\n"
|
||||||
|
" nMinVer = %d\n"
|
||||||
|
" nMaxVer = %d\n"
|
||||||
|
" setSubVer = %s\n"
|
||||||
|
" nPriority = %d\n"
|
||||||
|
" strComment = \"%s\"\n"
|
||||||
|
" strStatusBar = \"%s\"\n"
|
||||||
|
")\n",
|
||||||
|
nVersion,
|
||||||
|
nRelayUntil,
|
||||||
|
nExpiration,
|
||||||
|
nID,
|
||||||
|
nCancel,
|
||||||
|
strSetCancel.c_str(),
|
||||||
|
nMinVer,
|
||||||
|
nMaxVer,
|
||||||
|
strSetSubVer.c_str(),
|
||||||
|
nPriority,
|
||||||
|
strComment.c_str(),
|
||||||
|
strStatusBar.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CUnsignedAlert::print() const
|
||||||
|
{
|
||||||
|
printf("%s", ToString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAlert::SetNull()
|
||||||
|
{
|
||||||
|
CUnsignedAlert::SetNull();
|
||||||
|
vchMsg.clear();
|
||||||
|
vchSig.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAlert::IsNull() const
|
||||||
|
{
|
||||||
|
return (nExpiration == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 CAlert::GetHash() const
|
||||||
|
{
|
||||||
|
return Hash(this->vchMsg.begin(), this->vchMsg.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAlert::IsInEffect() const
|
||||||
|
{
|
||||||
|
return (GetAdjustedTime() < nExpiration);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAlert::Cancels(const CAlert& alert) const
|
||||||
|
{
|
||||||
|
if (!IsInEffect())
|
||||||
|
return false; // this was a no-op before 31403
|
||||||
|
return (alert.nID <= nCancel || setCancel.count(alert.nID));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAlert::AppliesTo(int nVersion, std::string strSubVerIn) const
|
||||||
|
{
|
||||||
|
// TODO: rework for client-version-embedded-in-strSubVer ?
|
||||||
|
return (IsInEffect() &&
|
||||||
|
nMinVer <= nVersion && nVersion <= nMaxVer &&
|
||||||
|
(setSubVer.empty() || setSubVer.count(strSubVerIn)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAlert::AppliesToMe() const
|
||||||
|
{
|
||||||
|
return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAlert::RelayTo(CNode* pnode) const
|
||||||
|
{
|
||||||
|
if (!IsInEffect())
|
||||||
|
return false;
|
||||||
|
// returns true if wasn't already contained in the set
|
||||||
|
if (pnode->setKnown.insert(GetHash()).second)
|
||||||
|
{
|
||||||
|
if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
|
||||||
|
AppliesToMe() ||
|
||||||
|
GetAdjustedTime() < nRelayUntil)
|
||||||
|
{
|
||||||
|
pnode->PushMessage("alert", *this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAlert::CheckSignature() const
|
||||||
|
{
|
||||||
|
CKey key;
|
||||||
|
if (!key.SetPubKey(ParseHex(fTestNet ? pszTestKey : pszMainKey)))
|
||||||
|
return error("CAlert::CheckSignature() : SetPubKey failed");
|
||||||
|
if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
|
||||||
|
return error("CAlert::CheckSignature() : verify signature failed");
|
||||||
|
|
||||||
|
// Now unserialize the data
|
||||||
|
CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
sMsg >> *(CUnsignedAlert*)this;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAlert CAlert::getAlertByHash(const uint256 &hash)
|
||||||
|
{
|
||||||
|
CAlert retval;
|
||||||
|
{
|
||||||
|
LOCK(cs_mapAlerts);
|
||||||
|
map<uint256, CAlert>::iterator mi = mapAlerts.find(hash);
|
||||||
|
if(mi != mapAlerts.end())
|
||||||
|
retval = mi->second;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAlert::ProcessAlert()
|
||||||
|
{
|
||||||
|
if (!CheckSignature())
|
||||||
|
return false;
|
||||||
|
if (!IsInEffect())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// alert.nID=max is reserved for if the alert key is
|
||||||
|
// compromised. It must have a pre-defined message,
|
||||||
|
// must never expire, must apply to all versions,
|
||||||
|
// and must cancel all previous
|
||||||
|
// alerts or it will be ignored (so an attacker can't
|
||||||
|
// send an "everything is OK, don't panic" version that
|
||||||
|
// cannot be overridden):
|
||||||
|
int maxInt = std::numeric_limits<int>::max();
|
||||||
|
if (nID == maxInt)
|
||||||
|
{
|
||||||
|
if (!(
|
||||||
|
nExpiration == maxInt &&
|
||||||
|
nCancel == (maxInt-1) &&
|
||||||
|
nMinVer == 0 &&
|
||||||
|
nMaxVer == maxInt &&
|
||||||
|
setSubVer.empty() &&
|
||||||
|
nPriority == maxInt &&
|
||||||
|
strStatusBar == "URGENT: Alert key compromised, upgrade required"
|
||||||
|
))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
LOCK(cs_mapAlerts);
|
||||||
|
// Cancel previous alerts
|
||||||
|
for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();)
|
||||||
|
{
|
||||||
|
const CAlert& alert = (*mi).second;
|
||||||
|
if (Cancels(alert))
|
||||||
|
{
|
||||||
|
printf("cancelling alert %d\n", alert.nID);
|
||||||
|
uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
|
||||||
|
mapAlerts.erase(mi++);
|
||||||
|
}
|
||||||
|
else if (!alert.IsInEffect())
|
||||||
|
{
|
||||||
|
printf("expiring alert %d\n", alert.nID);
|
||||||
|
uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
|
||||||
|
mapAlerts.erase(mi++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this alert has been cancelled
|
||||||
|
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
|
||||||
|
{
|
||||||
|
const CAlert& alert = item.second;
|
||||||
|
if (alert.Cancels(*this))
|
||||||
|
{
|
||||||
|
printf("alert already cancelled by %d\n", alert.nID);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to mapAlerts
|
||||||
|
mapAlerts.insert(make_pair(GetHash(), *this));
|
||||||
|
// Notify UI if it applies to me
|
||||||
|
if(AppliesToMe())
|
||||||
|
uiInterface.NotifyAlertChanged(GetHash(), CT_NEW);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
|
||||||
|
return true;
|
||||||
|
}
|
102
src/alert.h
Normal file
102
src/alert.h
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
// Copyright (c) 2010 Satoshi Nakamoto
|
||||||
|
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef _BITCOINALERT_H_
|
||||||
|
#define _BITCOINALERT_H_ 1
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "uint256.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
class CNode;
|
||||||
|
|
||||||
|
/** Alerts are for notifying old versions if they become too obsolete and
|
||||||
|
* need to upgrade. The message is displayed in the status bar.
|
||||||
|
* Alert messages are broadcast as a vector of signed data. Unserializing may
|
||||||
|
* not read the entire buffer if the alert is for a newer version, but older
|
||||||
|
* versions can still relay the original data.
|
||||||
|
*/
|
||||||
|
class CUnsignedAlert
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int nVersion;
|
||||||
|
int64 nRelayUntil; // when newer nodes stop relaying to newer nodes
|
||||||
|
int64 nExpiration;
|
||||||
|
int nID;
|
||||||
|
int nCancel;
|
||||||
|
std::set<int> setCancel;
|
||||||
|
int nMinVer; // lowest version inclusive
|
||||||
|
int nMaxVer; // highest version inclusive
|
||||||
|
std::set<std::string> setSubVer; // empty matches all
|
||||||
|
int nPriority;
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
std::string strComment;
|
||||||
|
std::string strStatusBar;
|
||||||
|
std::string strReserved;
|
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE
|
||||||
|
(
|
||||||
|
READWRITE(this->nVersion);
|
||||||
|
nVersion = this->nVersion;
|
||||||
|
READWRITE(nRelayUntil);
|
||||||
|
READWRITE(nExpiration);
|
||||||
|
READWRITE(nID);
|
||||||
|
READWRITE(nCancel);
|
||||||
|
READWRITE(setCancel);
|
||||||
|
READWRITE(nMinVer);
|
||||||
|
READWRITE(nMaxVer);
|
||||||
|
READWRITE(setSubVer);
|
||||||
|
READWRITE(nPriority);
|
||||||
|
|
||||||
|
READWRITE(strComment);
|
||||||
|
READWRITE(strStatusBar);
|
||||||
|
READWRITE(strReserved);
|
||||||
|
)
|
||||||
|
|
||||||
|
void SetNull();
|
||||||
|
|
||||||
|
std::string ToString() const;
|
||||||
|
void print() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** An alert is a combination of a serialized CUnsignedAlert and a signature. */
|
||||||
|
class CAlert : public CUnsignedAlert
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<unsigned char> vchMsg;
|
||||||
|
std::vector<unsigned char> vchSig;
|
||||||
|
|
||||||
|
CAlert()
|
||||||
|
{
|
||||||
|
SetNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE
|
||||||
|
(
|
||||||
|
READWRITE(vchMsg);
|
||||||
|
READWRITE(vchSig);
|
||||||
|
)
|
||||||
|
|
||||||
|
void SetNull();
|
||||||
|
bool IsNull() const;
|
||||||
|
uint256 GetHash() const;
|
||||||
|
bool IsInEffect() const;
|
||||||
|
bool Cancels(const CAlert& alert) const;
|
||||||
|
bool AppliesTo(int nVersion, std::string strSubVerIn) const;
|
||||||
|
bool AppliesToMe() const;
|
||||||
|
bool RelayTo(CNode* pnode) const;
|
||||||
|
bool CheckSignature() const;
|
||||||
|
bool ProcessAlert();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get copy of (active) alert object by hash. Returns a null alert if it is not found.
|
||||||
|
*/
|
||||||
|
static CAlert getAlertByHash(const uint256 &hash);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
90
src/main.cpp
90
src/main.cpp
|
@ -3,6 +3,7 @@
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "alert.h"
|
||||||
#include "checkpoints.h"
|
#include "checkpoints.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
@ -2262,8 +2263,8 @@ bool LoadExternalBlockFile(FILE* fileIn)
|
||||||
// CAlert
|
// CAlert
|
||||||
//
|
//
|
||||||
|
|
||||||
map<uint256, CAlert> mapAlerts;
|
extern map<uint256, CAlert> mapAlerts;
|
||||||
CCriticalSection cs_mapAlerts;
|
extern CCriticalSection cs_mapAlerts;
|
||||||
|
|
||||||
string GetWarnings(string strFor)
|
string GetWarnings(string strFor)
|
||||||
{
|
{
|
||||||
|
@ -2309,91 +2310,6 @@ string GetWarnings(string strFor)
|
||||||
return "error";
|
return "error";
|
||||||
}
|
}
|
||||||
|
|
||||||
CAlert CAlert::getAlertByHash(const uint256 &hash)
|
|
||||||
{
|
|
||||||
CAlert retval;
|
|
||||||
{
|
|
||||||
LOCK(cs_mapAlerts);
|
|
||||||
map<uint256, CAlert>::iterator mi = mapAlerts.find(hash);
|
|
||||||
if(mi != mapAlerts.end())
|
|
||||||
retval = mi->second;
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CAlert::ProcessAlert()
|
|
||||||
{
|
|
||||||
if (!CheckSignature())
|
|
||||||
return false;
|
|
||||||
if (!IsInEffect())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// alert.nID=max is reserved for if the alert key is
|
|
||||||
// compromised. It must have a pre-defined message,
|
|
||||||
// must never expire, must apply to all versions,
|
|
||||||
// and must cancel all previous
|
|
||||||
// alerts or it will be ignored (so an attacker can't
|
|
||||||
// send an "everything is OK, don't panic" version that
|
|
||||||
// cannot be overridden):
|
|
||||||
int maxInt = std::numeric_limits<int>::max();
|
|
||||||
if (nID == maxInt)
|
|
||||||
{
|
|
||||||
if (!(
|
|
||||||
nExpiration == maxInt &&
|
|
||||||
nCancel == (maxInt-1) &&
|
|
||||||
nMinVer == 0 &&
|
|
||||||
nMaxVer == maxInt &&
|
|
||||||
setSubVer.empty() &&
|
|
||||||
nPriority == maxInt &&
|
|
||||||
strStatusBar == "URGENT: Alert key compromised, upgrade required"
|
|
||||||
))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
LOCK(cs_mapAlerts);
|
|
||||||
// Cancel previous alerts
|
|
||||||
for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();)
|
|
||||||
{
|
|
||||||
const CAlert& alert = (*mi).second;
|
|
||||||
if (Cancels(alert))
|
|
||||||
{
|
|
||||||
printf("cancelling alert %d\n", alert.nID);
|
|
||||||
uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
|
|
||||||
mapAlerts.erase(mi++);
|
|
||||||
}
|
|
||||||
else if (!alert.IsInEffect())
|
|
||||||
{
|
|
||||||
printf("expiring alert %d\n", alert.nID);
|
|
||||||
uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
|
|
||||||
mapAlerts.erase(mi++);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mi++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if this alert has been cancelled
|
|
||||||
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
|
|
||||||
{
|
|
||||||
const CAlert& alert = item.second;
|
|
||||||
if (alert.Cancels(*this))
|
|
||||||
{
|
|
||||||
printf("alert already cancelled by %d\n", alert.nID);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to mapAlerts
|
|
||||||
mapAlerts.insert(make_pair(GetHash(), *this));
|
|
||||||
// Notify UI if it applies to me
|
|
||||||
if(AppliesToMe())
|
|
||||||
uiInterface.NotifyAlertChanged(GetHash(), CT_NEW);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
206
src/main.h
206
src/main.h
|
@ -1397,212 +1397,6 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Alerts are for notifying old versions if they become too obsolete and
|
|
||||||
* need to upgrade. The message is displayed in the status bar.
|
|
||||||
* Alert messages are broadcast as a vector of signed data. Unserializing may
|
|
||||||
* not read the entire buffer if the alert is for a newer version, but older
|
|
||||||
* versions can still relay the original data.
|
|
||||||
*/
|
|
||||||
class CUnsignedAlert
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int nVersion;
|
|
||||||
int64 nRelayUntil; // when newer nodes stop relaying to newer nodes
|
|
||||||
int64 nExpiration;
|
|
||||||
int nID;
|
|
||||||
int nCancel;
|
|
||||||
std::set<int> setCancel;
|
|
||||||
int nMinVer; // lowest version inclusive
|
|
||||||
int nMaxVer; // highest version inclusive
|
|
||||||
std::set<std::string> setSubVer; // empty matches all
|
|
||||||
int nPriority;
|
|
||||||
|
|
||||||
// Actions
|
|
||||||
std::string strComment;
|
|
||||||
std::string strStatusBar;
|
|
||||||
std::string strReserved;
|
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
|
||||||
(
|
|
||||||
READWRITE(this->nVersion);
|
|
||||||
nVersion = this->nVersion;
|
|
||||||
READWRITE(nRelayUntil);
|
|
||||||
READWRITE(nExpiration);
|
|
||||||
READWRITE(nID);
|
|
||||||
READWRITE(nCancel);
|
|
||||||
READWRITE(setCancel);
|
|
||||||
READWRITE(nMinVer);
|
|
||||||
READWRITE(nMaxVer);
|
|
||||||
READWRITE(setSubVer);
|
|
||||||
READWRITE(nPriority);
|
|
||||||
|
|
||||||
READWRITE(strComment);
|
|
||||||
READWRITE(strStatusBar);
|
|
||||||
READWRITE(strReserved);
|
|
||||||
)
|
|
||||||
|
|
||||||
void SetNull()
|
|
||||||
{
|
|
||||||
nVersion = 1;
|
|
||||||
nRelayUntil = 0;
|
|
||||||
nExpiration = 0;
|
|
||||||
nID = 0;
|
|
||||||
nCancel = 0;
|
|
||||||
setCancel.clear();
|
|
||||||
nMinVer = 0;
|
|
||||||
nMaxVer = 0;
|
|
||||||
setSubVer.clear();
|
|
||||||
nPriority = 0;
|
|
||||||
|
|
||||||
strComment.clear();
|
|
||||||
strStatusBar.clear();
|
|
||||||
strReserved.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ToString() const
|
|
||||||
{
|
|
||||||
std::string strSetCancel;
|
|
||||||
BOOST_FOREACH(int n, setCancel)
|
|
||||||
strSetCancel += strprintf("%d ", n);
|
|
||||||
std::string strSetSubVer;
|
|
||||||
BOOST_FOREACH(std::string str, setSubVer)
|
|
||||||
strSetSubVer += "\"" + str + "\" ";
|
|
||||||
return strprintf(
|
|
||||||
"CAlert(\n"
|
|
||||||
" nVersion = %d\n"
|
|
||||||
" nRelayUntil = %"PRI64d"\n"
|
|
||||||
" nExpiration = %"PRI64d"\n"
|
|
||||||
" nID = %d\n"
|
|
||||||
" nCancel = %d\n"
|
|
||||||
" setCancel = %s\n"
|
|
||||||
" nMinVer = %d\n"
|
|
||||||
" nMaxVer = %d\n"
|
|
||||||
" setSubVer = %s\n"
|
|
||||||
" nPriority = %d\n"
|
|
||||||
" strComment = \"%s\"\n"
|
|
||||||
" strStatusBar = \"%s\"\n"
|
|
||||||
")\n",
|
|
||||||
nVersion,
|
|
||||||
nRelayUntil,
|
|
||||||
nExpiration,
|
|
||||||
nID,
|
|
||||||
nCancel,
|
|
||||||
strSetCancel.c_str(),
|
|
||||||
nMinVer,
|
|
||||||
nMaxVer,
|
|
||||||
strSetSubVer.c_str(),
|
|
||||||
nPriority,
|
|
||||||
strComment.c_str(),
|
|
||||||
strStatusBar.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void print() const
|
|
||||||
{
|
|
||||||
printf("%s", ToString().c_str());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** An alert is a combination of a serialized CUnsignedAlert and a signature. */
|
|
||||||
class CAlert : public CUnsignedAlert
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::vector<unsigned char> vchMsg;
|
|
||||||
std::vector<unsigned char> vchSig;
|
|
||||||
|
|
||||||
CAlert()
|
|
||||||
{
|
|
||||||
SetNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
|
||||||
(
|
|
||||||
READWRITE(vchMsg);
|
|
||||||
READWRITE(vchSig);
|
|
||||||
)
|
|
||||||
|
|
||||||
void SetNull()
|
|
||||||
{
|
|
||||||
CUnsignedAlert::SetNull();
|
|
||||||
vchMsg.clear();
|
|
||||||
vchSig.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsNull() const
|
|
||||||
{
|
|
||||||
return (nExpiration == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint256 GetHash() const
|
|
||||||
{
|
|
||||||
return Hash(this->vchMsg.begin(), this->vchMsg.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsInEffect() const
|
|
||||||
{
|
|
||||||
return (GetAdjustedTime() < nExpiration);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Cancels(const CAlert& alert) const
|
|
||||||
{
|
|
||||||
if (!IsInEffect())
|
|
||||||
return false; // this was a no-op before 31403
|
|
||||||
return (alert.nID <= nCancel || setCancel.count(alert.nID));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AppliesTo(int nVersion, std::string strSubVerIn) const
|
|
||||||
{
|
|
||||||
// TODO: rework for client-version-embedded-in-strSubVer ?
|
|
||||||
return (IsInEffect() &&
|
|
||||||
nMinVer <= nVersion && nVersion <= nMaxVer &&
|
|
||||||
(setSubVer.empty() || setSubVer.count(strSubVerIn)));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AppliesToMe() const
|
|
||||||
{
|
|
||||||
return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RelayTo(CNode* pnode) const
|
|
||||||
{
|
|
||||||
if (!IsInEffect())
|
|
||||||
return false;
|
|
||||||
// returns true if wasn't already contained in the set
|
|
||||||
if (pnode->setKnown.insert(GetHash()).second)
|
|
||||||
{
|
|
||||||
if (AppliesTo(pnode->nVersion, pnode->strSubVer) ||
|
|
||||||
AppliesToMe() ||
|
|
||||||
GetAdjustedTime() < nRelayUntil)
|
|
||||||
{
|
|
||||||
pnode->PushMessage("alert", *this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CheckSignature()
|
|
||||||
{
|
|
||||||
CKey key;
|
|
||||||
if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284")))
|
|
||||||
return error("CAlert::CheckSignature() : SetPubKey failed");
|
|
||||||
if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
|
|
||||||
return error("CAlert::CheckSignature() : verify signature failed");
|
|
||||||
|
|
||||||
// Now unserialize the data
|
|
||||||
CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION);
|
|
||||||
sMsg >> *(CUnsignedAlert*)this;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ProcessAlert();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get copy of (active) alert object by hash. Returns a null alert if it is not found.
|
|
||||||
*/
|
|
||||||
static CAlert getAlertByHash(const uint256 &hash);
|
|
||||||
};
|
|
||||||
|
|
||||||
class CTxMemPool
|
class CTxMemPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -56,6 +56,7 @@ LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l w
|
||||||
HEADERS = $(wildcard *.h)
|
HEADERS = $(wildcard *.h)
|
||||||
|
|
||||||
OBJS= \
|
OBJS= \
|
||||||
|
obj/alert.o \
|
||||||
obj/version.o \
|
obj/version.o \
|
||||||
obj/checkpoints.o \
|
obj/checkpoints.o \
|
||||||
obj/netbase.o \
|
obj/netbase.o \
|
||||||
|
|
|
@ -52,6 +52,7 @@ LIBS += -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell
|
||||||
HEADERS = $(wildcard *.h)
|
HEADERS = $(wildcard *.h)
|
||||||
|
|
||||||
OBJS= \
|
OBJS= \
|
||||||
|
obj/alert.o \
|
||||||
obj/version.o \
|
obj/version.o \
|
||||||
obj/checkpoints.o \
|
obj/checkpoints.o \
|
||||||
obj/netbase.o \
|
obj/netbase.o \
|
||||||
|
|
|
@ -70,6 +70,7 @@ CFLAGS += -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \
|
||||||
$(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
|
$(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
|
||||||
|
|
||||||
OBJS= \
|
OBJS= \
|
||||||
|
obj/alert.o \
|
||||||
obj/version.o \
|
obj/version.o \
|
||||||
obj/checkpoints.o \
|
obj/checkpoints.o \
|
||||||
obj/netbase.o \
|
obj/netbase.o \
|
||||||
|
|
|
@ -101,6 +101,7 @@ xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-para
|
||||||
xLDFLAGS=$(LDHARDENING) $(LDFLAGS)
|
xLDFLAGS=$(LDHARDENING) $(LDFLAGS)
|
||||||
|
|
||||||
OBJS= \
|
OBJS= \
|
||||||
|
obj/alert.o \
|
||||||
obj/version.o \
|
obj/version.o \
|
||||||
obj/checkpoints.o \
|
obj/checkpoints.o \
|
||||||
obj/netbase.o \
|
obj/netbase.o \
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "addresstablemodel.h"
|
#include "addresstablemodel.h"
|
||||||
#include "transactiontablemodel.h"
|
#include "transactiontablemodel.h"
|
||||||
|
|
||||||
|
#include "alert.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue