diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index a41d39d51..9e7de0f98 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -1,134 +1,134 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "macdockiconhandler.h" #include #include #include #include #undef slots #include #include #include #if QT_VERSION < 0x050000 extern void qt_mac_set_dock_menu(QMenu *); #endif -static MacDockIconHandler *s_instance = NULL; +static MacDockIconHandler *s_instance = nullptr; bool dockClickHandler(id self,SEL _cmd,...) { Q_UNUSED(self) Q_UNUSED(_cmd) s_instance->handleDockIconClickEvent(); // Return NO (false) to suppress the default OS X actions return false; } void setupDockClickHandler() { Class cls = objc_getClass("NSApplication"); id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication")); - if (appInst != NULL) { + if (appInst != nullptr) { id delegate = objc_msgSend(appInst, sel_registerName("delegate")); Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class")); SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"); if (class_getInstanceMethod(delClass, shouldHandle)) class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"); else class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"B@:"); } } MacDockIconHandler::MacDockIconHandler() : QObject() { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; setupDockClickHandler(); this->m_dummyWidget = new QWidget(); this->m_dockMenu = new QMenu(this->m_dummyWidget); - this->setMainWindow(NULL); + this->setMainWindow(nullptr); #if QT_VERSION < 0x050000 qt_mac_set_dock_menu(this->m_dockMenu); #elif QT_VERSION >= 0x050200 this->m_dockMenu->setAsDockMenu(); #endif [pool release]; } void MacDockIconHandler::setMainWindow(QMainWindow *window) { this->mainWindow = window; } MacDockIconHandler::~MacDockIconHandler() { delete this->m_dummyWidget; - this->setMainWindow(NULL); + this->setMainWindow(nullptr); } QMenu *MacDockIconHandler::dockMenu() { return this->m_dockMenu; } void MacDockIconHandler::setIcon(const QIcon &icon) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSImage *image = nil; if (icon.isNull()) image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; else { // generate NSImage from QIcon and use this as dock icon. QSize size = icon.actualSize(QSize(128, 128)); QPixmap pixmap = icon.pixmap(size); // Write image into a R/W buffer from raw pixmap, then save the image. QBuffer notificationBuffer; if (!pixmap.isNull() && notificationBuffer.open(QIODevice::ReadWrite)) { QImageWriter writer(¬ificationBuffer, "PNG"); if (writer.write(pixmap.toImage())) { NSData* macImgData = [NSData dataWithBytes:notificationBuffer.buffer().data() length:notificationBuffer.buffer().size()]; image = [[NSImage alloc] initWithData:macImgData]; } } if(!image) { // if testnet image could not be created, load std. app icon image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; } } [NSApp setApplicationIconImage:image]; [image release]; [pool release]; } MacDockIconHandler *MacDockIconHandler::instance() { if (!s_instance) s_instance = new MacDockIconHandler(); return s_instance; } void MacDockIconHandler::cleanup() { delete s_instance; } void MacDockIconHandler::handleDockIconClickEvent() { if (this->mainWindow) { this->mainWindow->activateWindow(); this->mainWindow->show(); } Q_EMIT this->dockIconClicked(); } diff --git a/src/qt/macnotificationhandler.mm b/src/qt/macnotificationhandler.mm index dd3f62281..4c96d08c8 100644 --- a/src/qt/macnotificationhandler.mm +++ b/src/qt/macnotificationhandler.mm @@ -1,91 +1,91 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "macnotificationhandler.h" #undef slots #import #include // Add an obj-c category (extension) to return the expected bundle identifier @implementation NSBundle(returnCorrectIdentifier) - (NSString *)__bundleIdentifier { if (self == [NSBundle mainBundle]) { return @"org.bitcoinfoundation.Bitcoin-Qt"; } else { return [self __bundleIdentifier]; } } @end void MacNotificationHandler::showNotification(const QString &title, const QString &text) { // check if users OS has support for NSUserNotification if(this->hasUserNotificationCenterSupport()) { // okay, seems like 10.8+ QByteArray utf8 = title.toUtf8(); char* cString = (char *)utf8.constData(); NSString *titleMac = [[NSString alloc] initWithUTF8String:cString]; utf8 = text.toUtf8(); cString = (char *)utf8.constData(); NSString *textMac = [[NSString alloc] initWithUTF8String:cString]; // do everything weak linked (because we will keep <10.8 compatibility) id userNotification = [[NSClassFromString(@"NSUserNotification") alloc] init]; [userNotification performSelector:@selector(setTitle:) withObject:titleMac]; [userNotification performSelector:@selector(setInformativeText:) withObject:textMac]; id notificationCenterInstance = [NSClassFromString(@"NSUserNotificationCenter") performSelector:@selector(defaultUserNotificationCenter)]; [notificationCenterInstance performSelector:@selector(deliverNotification:) withObject:userNotification]; [titleMac release]; [textMac release]; [userNotification release]; } } // sendAppleScript just take a QString and executes it as apple script void MacNotificationHandler::sendAppleScript(const QString &script) { QByteArray utf8 = script.toUtf8(); char* cString = (char *)utf8.constData(); NSString *scriptApple = [[NSString alloc] initWithUTF8String:cString]; NSAppleScript *as = [[NSAppleScript alloc] initWithSource:scriptApple]; NSDictionary *err = nil; [as executeAndReturnError:&err]; [as release]; [scriptApple release]; } bool MacNotificationHandler::hasUserNotificationCenterSupport(void) { Class possibleClass = NSClassFromString(@"NSUserNotificationCenter"); // check if users OS has support for NSUserNotification if(possibleClass!=nil) { return true; } return false; } MacNotificationHandler *MacNotificationHandler::instance() { - static MacNotificationHandler *s_instance = NULL; + static MacNotificationHandler *s_instance = nullptr; if (!s_instance) { s_instance = new MacNotificationHandler(); Class aPossibleClass = objc_getClass("NSBundle"); if (aPossibleClass) { // change NSBundle -bundleIdentifier method to return a correct bundle identifier // a bundle identifier is required to use OSXs User Notification Center method_exchangeImplementations(class_getInstanceMethod(aPossibleClass, @selector(bundleIdentifier)), class_getInstanceMethod(aPossibleClass, @selector(__bundleIdentifier))); } } return s_instance; } diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index 4090970ec..5b22544a7 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -1,94 +1,94 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_BITCOINCONSENSUS_H #define BITCOIN_BITCOINCONSENSUS_H #include #if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" #if defined(_WIN32) #if defined(DLL_EXPORT) #if defined(HAVE_FUNC_ATTRIBUTE_DLLEXPORT) #define EXPORT_SYMBOL __declspec(dllexport) #else #define EXPORT_SYMBOL #endif #endif #elif defined(HAVE_FUNC_ATTRIBUTE_VISIBILITY) #define EXPORT_SYMBOL __attribute__((visibility("default"))) #endif #elif defined(MSC_VER) && !defined(STATIC_LIBBITCOINCONSENSUS) #define EXPORT_SYMBOL __declspec(dllimport) #endif #ifndef EXPORT_SYMBOL #define EXPORT_SYMBOL #endif #ifdef __cplusplus extern "C" { #endif #define BITCOINCONSENSUS_API_VER 1 typedef enum bitcoinconsensus_error_t { bitcoinconsensus_ERR_OK = 0, bitcoinconsensus_ERR_TX_INDEX, bitcoinconsensus_ERR_TX_SIZE_MISMATCH, bitcoinconsensus_ERR_TX_DESERIALIZE, bitcoinconsensus_ERR_AMOUNT_REQUIRED, bitcoinconsensus_ERR_INVALID_FLAGS, } bitcoinconsensus_error; /** Script verification flags */ enum { bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0, // evaluate P2SH (BIP16) subscripts bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // enforce strict DER (BIP66) compliance bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce NULLDUMMY (BIP147) bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY = (1U << 4), // enable CHECKLOCKTIMEVERIFY (BIP65) bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKSEQUENCEVERIFY (BIP112) bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), // enable WITNESS (BIP141) bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS_DEPRECATED = (1U << 11), // enable SIGHASH_FORKID replay protection bitcoinconsensus_SCRIPT_ENABLE_SIGHASH_FORKID = (1U << 16), bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL = bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY, }; /// Returns 1 if the input nIn of the serialized transaction pointed to by txTo /// correctly spends the scriptPubKey pointed to by scriptPubKey under the /// additional constraints specified by flags. -/// If not NULL, err will contain an error/success code for the operation +/// If not nullptr, err will contain an error/success code for the operation EXPORT_SYMBOL int bitcoinconsensus_verify_script( const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, const unsigned char *txTo, unsigned int txToLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error *err); EXPORT_SYMBOL int bitcoinconsensus_verify_script_with_amount( const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount, const unsigned char *txTo, unsigned int txToLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error *err); EXPORT_SYMBOL unsigned int bitcoinconsensus_version(); #ifdef __cplusplus } // extern "C" #endif #undef EXPORT_SYMBOL #endif // BITCOIN_BITCOINCONSENSUS_H diff --git a/src/script/interpreter.h b/src/script/interpreter.h index e00cee71b..9972426d6 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -1,193 +1,194 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_SCRIPT_INTERPRETER_H #define BITCOIN_SCRIPT_INTERPRETER_H #include "primitives/transaction.h" #include "script_error.h" #include #include #include class CPubKey; class CScript; class CTransaction; class uint256; /** Signature hash types/flags */ enum { SIGHASH_ALL = 1, SIGHASH_NONE = 2, SIGHASH_SINGLE = 3, SIGHASH_FORKID = 0x40, SIGHASH_ANYONECANPAY = 0x80, }; /** Script verification flags */ enum { SCRIPT_VERIFY_NONE = 0, // Evaluate P2SH subscripts (softfork safe, BIP16). SCRIPT_VERIFY_P2SH = (1U << 0), // Passing a non-strict-DER signature or one with undefined hashtype to a // checksig operation causes script failure. Evaluating a pubkey that is not // (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes script // failure. // (softfork safe, but not used or intended as a consensus rule). SCRIPT_VERIFY_STRICTENC = (1U << 1), // Passing a non-strict-DER signature to a checksig operation causes script // failure (softfork safe, BIP62 rule 1) SCRIPT_VERIFY_DERSIG = (1U << 2), // Passing a non-strict-DER signature or one with S > order/2 to a checksig // operation causes script failure // (softfork safe, BIP62 rule 5). SCRIPT_VERIFY_LOW_S = (1U << 3), // verify dummy stack item consumed by CHECKMULTISIG is of zero-length // (softfork safe, BIP62 rule 7). SCRIPT_VERIFY_NULLDUMMY = (1U << 4), // Using a non-push operator in the scriptSig causes script failure // (softfork safe, BIP62 rule 2). SCRIPT_VERIFY_SIGPUSHONLY = (1U << 5), // Require minimal encodings for all push operations (OP_0... OP_16, // OP_1NEGATE where possible, direct pushes up to 75 bytes, OP_PUSHDATA up // to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating any other // push causes the script to fail (BIP62 rule 3). In addition, whenever a // stack element is interpreted as a number, it must be of minimal length // (BIP62 rule 4). // (softfork safe) SCRIPT_VERIFY_MINIMALDATA = (1U << 6), // Discourage use of NOPs reserved for upgrades (NOP1-10) // // Provided so that nodes can avoid accepting or mining transactions // containing executed NOP's whose meaning may change after a soft-fork, // thus rendering the script invalid; with this flag set executing // discouraged NOPs fails the script. This verification flag will never be a // mandatory flag applied to scripts in a block. NOPs that are not executed, // e.g. within an unexecuted IF ENDIF block, are *not* rejected. SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7), // Require that only a single stack element remains after evaluation. This // changes the success criterion from "At least one stack element must // remain, and when interpreted as a boolean, it must be true" to "Exactly // one stack element must remain, and when interpreted as a boolean, it must // be true". // (softfork safe, BIP62 rule 6) // Note: CLEANSTACK should never be used without P2SH or WITNESS. SCRIPT_VERIFY_CLEANSTACK = (1U << 8), // Verify CHECKLOCKTIMEVERIFY // // See BIP65 for details. SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // support CHECKSEQUENCEVERIFY opcode // // See BIP112 for details SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), // Making v1-v16 witness program non-standard // SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM = (1U << 12), // Segwit script only: Require the argument of OP_IF/NOTIF to be exactly // 0x01 or empty vector // SCRIPT_VERIFY_MINIMALIF = (1U << 13), // Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed // SCRIPT_VERIFY_NULLFAIL = (1U << 14), // Public keys in scripts must be compressed // SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE = (1U << 15), // Do we accept signature using SIGHASH_FORKID // SCRIPT_ENABLE_SIGHASH_FORKID = (1U << 16), }; bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError *serror); uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, unsigned int nIn, uint32_t nHashType, const CAmount &amount, - const PrecomputedTransactionData *cache = NULL); + const PrecomputedTransactionData *cache = nullptr); class BaseSignatureChecker { public: virtual bool CheckSig(const std::vector &scriptSig, const std::vector &vchPubKey, const CScript &scriptCode) const { return false; } virtual bool CheckLockTime(const CScriptNum &nLockTime) const { return false; } virtual bool CheckSequence(const CScriptNum &nSequence) const { return false; } virtual ~BaseSignatureChecker() {} }; class TransactionSignatureChecker : public BaseSignatureChecker { private: const CTransaction *txTo; unsigned int nIn; const CAmount amount; const PrecomputedTransactionData *txdata; protected: virtual bool VerifySignature(const std::vector &vchSig, const CPubKey &vchPubKey, const uint256 &sighash) const; public: TransactionSignatureChecker(const CTransaction *txToIn, unsigned int nInIn, const CAmount &amountIn) - : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(NULL) {} + : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(nullptr) {} TransactionSignatureChecker(const CTransaction *txToIn, unsigned int nInIn, const CAmount &amountIn, const PrecomputedTransactionData &txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {} bool CheckSig(const std::vector &scriptSig, const std::vector &vchPubKey, const CScript &scriptCode) const; bool CheckLockTime(const CScriptNum &nLockTime) const; bool CheckSequence(const CScriptNum &nSequence) const; }; class MutableTransactionSignatureChecker : public TransactionSignatureChecker { private: const CTransaction txTo; public: MutableTransactionSignatureChecker(const CMutableTransaction *txToIn, unsigned int nInIn, const CAmount &amount) : TransactionSignatureChecker(&txTo, nInIn, amount), txTo(*txToIn) {} }; bool EvalScript(std::vector> &stack, const CScript &script, unsigned int flags, - const BaseSignatureChecker &checker, ScriptError *error = NULL); + const BaseSignatureChecker &checker, + ScriptError *error = nullptr); bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, unsigned int flags, const BaseSignatureChecker &checker, - ScriptError *serror = NULL); + ScriptError *serror = nullptr); #endif // BITCOIN_SCRIPT_INTERPRETER_H diff --git a/src/script/script.h b/src/script/script.h index 758599c52..963478036 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -1,644 +1,644 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_SCRIPT_SCRIPT_H #define BITCOIN_SCRIPT_SCRIPT_H #include "crypto/common.h" #include "prevector.h" #include #include #include #include #include #include #include #include // Maximum number of bytes pushable to the stack static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // Maximum number of non-push operations per script static const int MAX_OPS_PER_SCRIPT = 201; // Maximum number of public keys per multisig static const int MAX_PUBKEYS_PER_MULTISIG = 20; // Maximum script length in bytes static const int MAX_SCRIPT_SIZE = 10000; // Threshold for nLockTime: below this value it is interpreted as block number, // otherwise as UNIX timestamp. Thresold is Tue Nov 5 00:53:20 1985 UTC static const unsigned int LOCKTIME_THRESHOLD = 500000000; template std::vector ToByteVector(const T &in) { return std::vector(in.begin(), in.end()); } /** Script opcodes */ enum opcodetype { // push value OP_0 = 0x00, OP_FALSE = OP_0, OP_PUSHDATA1 = 0x4c, OP_PUSHDATA2 = 0x4d, OP_PUSHDATA4 = 0x4e, OP_1NEGATE = 0x4f, OP_RESERVED = 0x50, OP_1 = 0x51, OP_TRUE = OP_1, OP_2 = 0x52, OP_3 = 0x53, OP_4 = 0x54, OP_5 = 0x55, OP_6 = 0x56, OP_7 = 0x57, OP_8 = 0x58, OP_9 = 0x59, OP_10 = 0x5a, OP_11 = 0x5b, OP_12 = 0x5c, OP_13 = 0x5d, OP_14 = 0x5e, OP_15 = 0x5f, OP_16 = 0x60, // control OP_NOP = 0x61, OP_VER = 0x62, OP_IF = 0x63, OP_NOTIF = 0x64, OP_VERIF = 0x65, OP_VERNOTIF = 0x66, OP_ELSE = 0x67, OP_ENDIF = 0x68, OP_VERIFY = 0x69, OP_RETURN = 0x6a, // stack ops OP_TOALTSTACK = 0x6b, OP_FROMALTSTACK = 0x6c, OP_2DROP = 0x6d, OP_2DUP = 0x6e, OP_3DUP = 0x6f, OP_2OVER = 0x70, OP_2ROT = 0x71, OP_2SWAP = 0x72, OP_IFDUP = 0x73, OP_DEPTH = 0x74, OP_DROP = 0x75, OP_DUP = 0x76, OP_NIP = 0x77, OP_OVER = 0x78, OP_PICK = 0x79, OP_ROLL = 0x7a, OP_ROT = 0x7b, OP_SWAP = 0x7c, OP_TUCK = 0x7d, // splice ops OP_CAT = 0x7e, OP_SUBSTR = 0x7f, OP_LEFT = 0x80, OP_RIGHT = 0x81, OP_SIZE = 0x82, // bit logic OP_INVERT = 0x83, OP_AND = 0x84, OP_OR = 0x85, OP_XOR = 0x86, OP_EQUAL = 0x87, OP_EQUALVERIFY = 0x88, OP_RESERVED1 = 0x89, OP_RESERVED2 = 0x8a, // numeric OP_1ADD = 0x8b, OP_1SUB = 0x8c, OP_2MUL = 0x8d, OP_2DIV = 0x8e, OP_NEGATE = 0x8f, OP_ABS = 0x90, OP_NOT = 0x91, OP_0NOTEQUAL = 0x92, OP_ADD = 0x93, OP_SUB = 0x94, OP_MUL = 0x95, OP_DIV = 0x96, OP_MOD = 0x97, OP_LSHIFT = 0x98, OP_RSHIFT = 0x99, OP_BOOLAND = 0x9a, OP_BOOLOR = 0x9b, OP_NUMEQUAL = 0x9c, OP_NUMEQUALVERIFY = 0x9d, OP_NUMNOTEQUAL = 0x9e, OP_LESSTHAN = 0x9f, OP_GREATERTHAN = 0xa0, OP_LESSTHANOREQUAL = 0xa1, OP_GREATERTHANOREQUAL = 0xa2, OP_MIN = 0xa3, OP_MAX = 0xa4, OP_WITHIN = 0xa5, // crypto OP_RIPEMD160 = 0xa6, OP_SHA1 = 0xa7, OP_SHA256 = 0xa8, OP_HASH160 = 0xa9, OP_HASH256 = 0xaa, OP_CODESEPARATOR = 0xab, OP_CHECKSIG = 0xac, OP_CHECKSIGVERIFY = 0xad, OP_CHECKMULTISIG = 0xae, OP_CHECKMULTISIGVERIFY = 0xaf, // expansion OP_NOP1 = 0xb0, OP_CHECKLOCKTIMEVERIFY = 0xb1, OP_NOP2 = OP_CHECKLOCKTIMEVERIFY, OP_CHECKSEQUENCEVERIFY = 0xb2, OP_NOP3 = OP_CHECKSEQUENCEVERIFY, OP_NOP4 = 0xb3, OP_NOP5 = 0xb4, OP_NOP6 = 0xb5, OP_NOP7 = 0xb6, OP_NOP8 = 0xb7, OP_NOP9 = 0xb8, OP_NOP10 = 0xb9, // template matching params OP_SMALLINTEGER = 0xfa, OP_PUBKEYS = 0xfb, OP_PUBKEYHASH = 0xfd, OP_PUBKEY = 0xfe, OP_INVALIDOPCODE = 0xff, }; const char *GetOpName(opcodetype opcode); class scriptnum_error : public std::runtime_error { public: explicit scriptnum_error(const std::string &str) : std::runtime_error(str) {} }; class CScriptNum { /** * Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte * integers. The semantics are subtle, though: operands must be in the range * [-2^31 +1...2^31 -1], but results may overflow (and are valid as long as * they are not used in a subsequent numeric operation). CScriptNum enforces * those semantics by storing results as an int64 and allowing out-of-range * values to be returned as a vector of bytes but throwing an exception if * arithmetic is done or the result is interpreted as an integer. */ public: explicit CScriptNum(const int64_t &n) { m_value = n; } static const size_t nDefaultMaxNumSize = 4; explicit CScriptNum(const std::vector &vch, bool fRequireMinimal, const size_t nMaxNumSize = nDefaultMaxNumSize) { if (vch.size() > nMaxNumSize) { throw scriptnum_error("script number overflow"); } if (fRequireMinimal && vch.size() > 0) { // Check that the number is encoded with the minimum possible number // of bytes. // // If the most-significant-byte - excluding the sign bit - is zero // then we're not minimal. Note how this test also rejects the // negative-zero encoding, 0x80. if ((vch.back() & 0x7f) == 0) { // One exception: if there's more than one byte and the most // significant bit of the second-most-significant-byte is set it // would conflict with the sign bit. An example of this case is // +-255, which encode to 0xff00 and 0xff80 respectively. // (big-endian). if (vch.size() <= 1 || (vch[vch.size() - 2] & 0x80) == 0) { throw scriptnum_error( "non-minimally encoded script number"); } } } m_value = set_vch(vch); } inline bool operator==(const int64_t &rhs) const { return m_value == rhs; } inline bool operator!=(const int64_t &rhs) const { return m_value != rhs; } inline bool operator<=(const int64_t &rhs) const { return m_value <= rhs; } inline bool operator<(const int64_t &rhs) const { return m_value < rhs; } inline bool operator>=(const int64_t &rhs) const { return m_value >= rhs; } inline bool operator>(const int64_t &rhs) const { return m_value > rhs; } inline bool operator==(const CScriptNum &rhs) const { return operator==(rhs.m_value); } inline bool operator!=(const CScriptNum &rhs) const { return operator!=(rhs.m_value); } inline bool operator<=(const CScriptNum &rhs) const { return operator<=(rhs.m_value); } inline bool operator<(const CScriptNum &rhs) const { return operator<(rhs.m_value); } inline bool operator>=(const CScriptNum &rhs) const { return operator>=(rhs.m_value); } inline bool operator>(const CScriptNum &rhs) const { return operator>(rhs.m_value); } inline CScriptNum operator+(const int64_t &rhs) const { return CScriptNum(m_value + rhs); } inline CScriptNum operator-(const int64_t &rhs) const { return CScriptNum(m_value - rhs); } inline CScriptNum operator+(const CScriptNum &rhs) const { return operator+(rhs.m_value); } inline CScriptNum operator-(const CScriptNum &rhs) const { return operator-(rhs.m_value); } inline CScriptNum &operator+=(const CScriptNum &rhs) { return operator+=(rhs.m_value); } inline CScriptNum &operator-=(const CScriptNum &rhs) { return operator-=(rhs.m_value); } inline CScriptNum operator&(const int64_t &rhs) const { return CScriptNum(m_value & rhs); } inline CScriptNum operator&(const CScriptNum &rhs) const { return operator&(rhs.m_value); } inline CScriptNum &operator&=(const CScriptNum &rhs) { return operator&=(rhs.m_value); } inline CScriptNum operator-() const { assert(m_value != std::numeric_limits::min()); return CScriptNum(-m_value); } inline CScriptNum &operator=(const int64_t &rhs) { m_value = rhs; return *this; } inline CScriptNum &operator+=(const int64_t &rhs) { assert( rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits::max() - rhs) || (rhs < 0 && m_value >= std::numeric_limits::min() - rhs)); m_value += rhs; return *this; } inline CScriptNum &operator-=(const int64_t &rhs) { assert( rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits::min() + rhs) || (rhs < 0 && m_value <= std::numeric_limits::max() + rhs)); m_value -= rhs; return *this; } inline CScriptNum &operator&=(const int64_t &rhs) { m_value &= rhs; return *this; } int getint() const { if (m_value > std::numeric_limits::max()) return std::numeric_limits::max(); else if (m_value < std::numeric_limits::min()) return std::numeric_limits::min(); return m_value; } std::vector getvch() const { return serialize(m_value); } static std::vector serialize(const int64_t &value) { if (value == 0) return std::vector(); std::vector result; const bool neg = value < 0; uint64_t absvalue = neg ? -value : value; while (absvalue) { result.push_back(absvalue & 0xff); absvalue >>= 8; } // - If the most significant byte is >= 0x80 and the value is positive, // push a new zero-byte to make the significant byte < 0x80 again. // - If the most significant byte is >= 0x80 and the value is negative, // push a new 0x80 byte that will be popped off when converting to an // integral. // - If the most significant byte is < 0x80 and the value is negative, // add 0x80 to it, since it will be subtracted and interpreted as a // negative when converting to an integral. if (result.back() & 0x80) { result.push_back(neg ? 0x80 : 0); } else if (neg) { result.back() |= 0x80; } return result; } private: static int64_t set_vch(const std::vector &vch) { if (vch.empty()) return 0; int64_t result = 0; for (size_t i = 0; i != vch.size(); ++i) result |= static_cast(vch[i]) << 8 * i; // If the input vector's most significant byte is 0x80, remove it from // the result's msb and return a negative. if (vch.back() & 0x80) return -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1))))); return result; } int64_t m_value; }; typedef prevector<28, unsigned char> CScriptBase; /** Serialized script, used inside transaction inputs and outputs */ class CScript : public CScriptBase { protected: CScript &push_int64(int64_t n) { if (n == -1 || (n >= 1 && n <= 16)) { push_back(n + (OP_1 - 1)); } else if (n == 0) { push_back(OP_0); } else { *this << CScriptNum::serialize(n); } return *this; } public: CScript() {} CScript(const_iterator pbegin, const_iterator pend) : CScriptBase(pbegin, pend) {} CScript(std::vector::const_iterator pbegin, std::vector::const_iterator pend) : CScriptBase(pbegin, pend) {} CScript(const unsigned char *pbegin, const unsigned char *pend) : CScriptBase(pbegin, pend) {} CScript &operator+=(const CScript &b) { insert(end(), b.begin(), b.end()); return *this; } friend CScript operator+(const CScript &a, const CScript &b) { CScript ret = a; ret += b; return ret; } CScript(int64_t b) { operator<<(b); } explicit CScript(opcodetype b) { operator<<(b); } explicit CScript(const CScriptNum &b) { operator<<(b); } explicit CScript(const std::vector &b) { operator<<(b); } CScript &operator<<(int64_t b) { return push_int64(b); } CScript &operator<<(opcodetype opcode) { if (opcode < 0 || opcode > 0xff) throw std::runtime_error("CScript::operator<<(): invalid opcode"); insert(end(), (unsigned char)opcode); return *this; } CScript &operator<<(const CScriptNum &b) { *this << b.getvch(); return *this; } CScript &operator<<(const std::vector &b) { if (b.size() < OP_PUSHDATA1) { insert(end(), (unsigned char)b.size()); } else if (b.size() <= 0xff) { insert(end(), OP_PUSHDATA1); insert(end(), (unsigned char)b.size()); } else if (b.size() <= 0xffff) { insert(end(), OP_PUSHDATA2); uint8_t data[2]; WriteLE16(data, b.size()); insert(end(), data, data + sizeof(data)); } else { insert(end(), OP_PUSHDATA4); uint8_t data[4]; WriteLE32(data, b.size()); insert(end(), data, data + sizeof(data)); } insert(end(), b.begin(), b.end()); return *this; } CScript &operator<<(const CScript &b) { // I'm not sure if this should push the script or concatenate scripts. // If there's ever a use for pushing a script onto a script, delete this // member fn. assert(!"Warning: Pushing a CScript onto a CScript with << is probably " "not intended, use + to concatenate!"); return *this; } bool GetOp(iterator &pc, opcodetype &opcodeRet, std::vector &vchRet) { // Wrapper so it can be called with either iterator or const_iterator. const_iterator pc2 = pc; bool fRet = GetOp2(pc2, opcodeRet, &vchRet); pc = begin() + (pc2 - begin()); return fRet; } bool GetOp(iterator &pc, opcodetype &opcodeRet) { const_iterator pc2 = pc; - bool fRet = GetOp2(pc2, opcodeRet, NULL); + bool fRet = GetOp2(pc2, opcodeRet, nullptr); pc = begin() + (pc2 - begin()); return fRet; } bool GetOp(const_iterator &pc, opcodetype &opcodeRet, std::vector &vchRet) const { return GetOp2(pc, opcodeRet, &vchRet); } bool GetOp(const_iterator &pc, opcodetype &opcodeRet) const { - return GetOp2(pc, opcodeRet, NULL); + return GetOp2(pc, opcodeRet, nullptr); } bool GetOp2(const_iterator &pc, opcodetype &opcodeRet, std::vector *pvchRet) const { opcodeRet = OP_INVALIDOPCODE; if (pvchRet) pvchRet->clear(); if (pc >= end()) return false; // Read instruction if (end() - pc < 1) return false; unsigned int opcode = *pc++; // Immediate operand if (opcode <= OP_PUSHDATA4) { unsigned int nSize = 0; if (opcode < OP_PUSHDATA1) { nSize = opcode; } else if (opcode == OP_PUSHDATA1) { if (end() - pc < 1) return false; nSize = *pc++; } else if (opcode == OP_PUSHDATA2) { if (end() - pc < 2) return false; nSize = ReadLE16(&pc[0]); pc += 2; } else if (opcode == OP_PUSHDATA4) { if (end() - pc < 4) return false; nSize = ReadLE32(&pc[0]); pc += 4; } if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize) return false; if (pvchRet) pvchRet->assign(pc, pc + nSize); pc += nSize; } opcodeRet = (opcodetype)opcode; return true; } /** Encode/decode small integers: */ static int DecodeOP_N(opcodetype opcode) { if (opcode == OP_0) return 0; assert(opcode >= OP_1 && opcode <= OP_16); return (int)opcode - (int)(OP_1 - 1); } static opcodetype EncodeOP_N(int n) { assert(n >= 0 && n <= 16); if (n == 0) return OP_0; return (opcodetype)(OP_1 + n - 1); } int FindAndDelete(const CScript &b) { int nFound = 0; if (b.empty()) return nFound; CScript result; iterator pc = begin(), pc2 = begin(); opcodetype opcode; do { result.insert(result.end(), pc2, pc); while (static_cast(end() - pc) >= b.size() && std::equal(b.begin(), b.end(), pc)) { pc = pc + b.size(); ++nFound; } pc2 = pc; } while (GetOp(pc, opcode)); if (nFound > 0) { result.insert(result.end(), pc2, end()); *this = result; } return nFound; } int Find(opcodetype op) const { int nFound = 0; opcodetype opcode; for (const_iterator pc = begin(); pc != end() && GetOp(pc, opcode);) if (opcode == op) ++nFound; return nFound; } /** * Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs as 20 sigops. With * pay-to-script-hash, that changed: CHECKMULTISIGs serialized in scriptSigs * are counted more accurately, assuming they are of the form * ... OP_N CHECKMULTISIG ... */ unsigned int GetSigOpCount(bool fAccurate) const; /** * Accurately count sigOps, including sigOps in pay-to-script-hash * transactions: */ unsigned int GetSigOpCount(const CScript &scriptSig) const; bool IsPayToScriptHash() const; bool IsPayToWitnessScriptHash() const; bool IsCommitment(const std::vector &data) const; bool IsWitnessProgram(int &version, std::vector &program) const; /** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it * consensus-critical). */ bool IsPushOnly(const_iterator pc) const; bool IsPushOnly() const; /** * Returns whether the script is guaranteed to fail at execution, regardless * of the initial stack. This allows outputs to be pruned instantly when * entering the UTXO set. */ bool IsUnspendable() const { return (size() > 0 && *begin() == OP_RETURN) || (size() > MAX_SCRIPT_SIZE); } void clear() { // The default std::vector::clear() does not release memory. CScriptBase().swap(*this); } }; struct CScriptWitness { // Note that this encodes the data elements being pushed, rather than // encoding them as a CScript that pushes them. std::vector> stack; // Some compilers complain without a default constructor CScriptWitness() {} bool IsNull() const { return stack.empty(); } void SetNull() { stack.clear(); stack.shrink_to_fit(); } std::string ToString() const; }; class CReserveScript { public: CScript reserveScript; virtual void KeepScript() {} CReserveScript() {} virtual ~CReserveScript() {} }; #endif // BITCOIN_SCRIPT_SCRIPT_H diff --git a/src/support/allocators/secure.h b/src/support/allocators/secure.h index d20038858..459d3a12e 100644 --- a/src/support/allocators/secure.h +++ b/src/support/allocators/secure.h @@ -1,54 +1,54 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_SUPPORT_ALLOCATORS_SECURE_H #define BITCOIN_SUPPORT_ALLOCATORS_SECURE_H #include "support/cleanse.h" #include "support/lockedpool.h" #include // // Allocator that locks its contents from being paged // out of memory and clears its contents before deletion. // template struct secure_allocator : public std::allocator { // MSVC8 default copy constructor is broken typedef std::allocator base; typedef typename base::size_type size_type; typedef typename base::difference_type difference_type; typedef typename base::pointer pointer; typedef typename base::const_pointer const_pointer; typedef typename base::reference reference; typedef typename base::const_reference const_reference; typedef typename base::value_type value_type; secure_allocator() throw() {} secure_allocator(const secure_allocator &a) throw() : base(a) {} template secure_allocator(const secure_allocator &a) throw() : base(a) {} ~secure_allocator() throw() {} template struct rebind { typedef secure_allocator<_Other> other; }; T *allocate(std::size_t n, const void *hint = 0) { return static_cast( LockedPoolManager::Instance().alloc(sizeof(T) * n)); } void deallocate(T *p, std::size_t n) { - if (p != NULL) { + if (p != nullptr) { memory_cleanse(p, sizeof(T) * n); } LockedPoolManager::Instance().free(p); } }; // This is exactly like std::string, but with a custom allocator. typedef std::basic_string, secure_allocator> SecureString; #endif // BITCOIN_SUPPORT_ALLOCATORS_SECURE_H diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h index d5e548c2d..34c168110 100644 --- a/src/support/allocators/zeroafterfree.h +++ b/src/support/allocators/zeroafterfree.h @@ -1,45 +1,45 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H #define BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H #include "support/cleanse.h" #include #include template struct zero_after_free_allocator : public std::allocator { // MSVC8 default copy constructor is broken typedef std::allocator base; typedef typename base::size_type size_type; typedef typename base::difference_type difference_type; typedef typename base::pointer pointer; typedef typename base::const_pointer const_pointer; typedef typename base::reference reference; typedef typename base::const_reference const_reference; typedef typename base::value_type value_type; zero_after_free_allocator() throw() {} zero_after_free_allocator(const zero_after_free_allocator &a) throw() : base(a) {} template zero_after_free_allocator(const zero_after_free_allocator &a) throw() : base(a) {} ~zero_after_free_allocator() throw() {} template struct rebind { typedef zero_after_free_allocator<_Other> other; }; void deallocate(T *p, std::size_t n) { - if (p != NULL) memory_cleanse(p, sizeof(T) * n); + if (p != nullptr) memory_cleanse(p, sizeof(T) * n); std::allocator::deallocate(p, n); } }; // Byte-vector that clears its contents before deletion. typedef std::vector> CSerializeData; #endif // BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 6e887bbe8..5ef84fa6e 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -1,149 +1,149 @@ // Copyright (c) 2015-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "zmqnotificationinterface.h" #include "zmqpublishnotifier.h" #include "streams.h" #include "util.h" #include "validation.h" #include "version.h" void zmqError(const char *str) { LogPrint("zmq", "zmq: Error: %s, errno=%s\n", str, zmq_strerror(errno)); } -CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL) {} +CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(nullptr) {} CZMQNotificationInterface::~CZMQNotificationInterface() { Shutdown(); for (std::list::iterator i = notifiers.begin(); i != notifiers.end(); ++i) { delete *i; } } CZMQNotificationInterface *CZMQNotificationInterface::Create() { - CZMQNotificationInterface *notificationInterface = NULL; + CZMQNotificationInterface *notificationInterface = nullptr; std::map factories; std::list notifiers; factories["pubhashblock"] = CZMQAbstractNotifier::Create; factories["pubhashtx"] = CZMQAbstractNotifier::Create; factories["pubrawblock"] = CZMQAbstractNotifier::Create; factories["pubrawtx"] = CZMQAbstractNotifier::Create; for (std::map::const_iterator i = factories.begin(); i != factories.end(); ++i) { std::string arg("-zmq" + i->first); if (IsArgSet(arg)) { CZMQNotifierFactory factory = i->second; std::string address = GetArg(arg, ""); CZMQAbstractNotifier *notifier = factory(); notifier->SetType(i->first); notifier->SetAddress(address); notifiers.push_back(notifier); } } if (!notifiers.empty()) { notificationInterface = new CZMQNotificationInterface(); notificationInterface->notifiers = notifiers; if (!notificationInterface->Initialize()) { delete notificationInterface; - notificationInterface = NULL; + notificationInterface = nullptr; } } return notificationInterface; } // Called at startup to conditionally set up ZMQ socket(s) bool CZMQNotificationInterface::Initialize() { LogPrint("zmq", "zmq: Initialize notification interface\n"); assert(!pcontext); pcontext = zmq_init(1); if (!pcontext) { zmqError("Unable to initialize context"); return false; } std::list::iterator i = notifiers.begin(); for (; i != notifiers.end(); ++i) { CZMQAbstractNotifier *notifier = *i; if (notifier->Initialize(pcontext)) { LogPrint("zmq", " Notifier %s ready (address = %s)\n", notifier->GetType(), notifier->GetAddress()); } else { LogPrint("zmq", " Notifier %s failed (address = %s)\n", notifier->GetType(), notifier->GetAddress()); break; } } if (i != notifiers.end()) { return false; } return true; } // Called during shutdown sequence void CZMQNotificationInterface::Shutdown() { LogPrint("zmq", "zmq: Shutdown notification interface\n"); if (pcontext) { for (std::list::iterator i = notifiers.begin(); i != notifiers.end(); ++i) { CZMQAbstractNotifier *notifier = *i; LogPrint("zmq", " Shutdown notifier %s at %s\n", notifier->GetType(), notifier->GetAddress()); notifier->Shutdown(); } zmq_ctx_destroy(pcontext); pcontext = 0; } } void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) { // In IBD or blocks were disconnected without any new ones if (fInitialDownload || pindexNew == pindexFork) return; for (std::list::iterator i = notifiers.begin(); i != notifiers.end();) { CZMQAbstractNotifier *notifier = *i; if (notifier->NotifyBlock(pindexNew)) { i++; } else { notifier->Shutdown(); i = notifiers.erase(i); } } } void CZMQNotificationInterface::SyncTransaction(const CTransaction &tx, const CBlockIndex *pindex, int posInBlock) { for (std::list::iterator i = notifiers.begin(); i != notifiers.end();) { CZMQAbstractNotifier *notifier = *i; if (notifier->NotifyTransaction(tx)) { i++; } else { notifier->Shutdown(); i = notifiers.erase(i); } } }