diff options
-rw-r--r-- | .travis.yml | 8 | ||||
-rwxr-xr-x | autogen.sh | 2 | ||||
-rw-r--r-- | depends/builders/darwin.mk | 2 | ||||
-rw-r--r-- | depends/builders/linux.mk | 2 | ||||
-rwxr-xr-x | qa/pull-tester/rpc-tests.py | 1 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/init.cpp | 12 | ||||
-rw-r--r-- | src/main.cpp | 2 | ||||
-rw-r--r-- | src/main.h | 3 | ||||
-rw-r--r-- | src/policy/policy.h | 1 | ||||
-rw-r--r-- | src/script/interpreter.cpp | 84 | ||||
-rw-r--r-- | src/script/interpreter.h | 11 | ||||
-rw-r--r-- | src/script/script.h | 12 | ||||
-rw-r--r-- | src/script/script_error.h | 2 | ||||
-rw-r--r-- | src/test/data/tx_invalid.json | 54 | ||||
-rw-r--r-- | src/test/data/tx_valid.json | 84 | ||||
-rw-r--r-- | src/test/transaction_tests.cpp | 3 | ||||
-rw-r--r-- | src/test/util_tests.cpp | 4 | ||||
-rw-r--r-- | src/wallet/db.cpp | 6 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 4 |
20 files changed, 281 insertions, 17 deletions
diff --git a/.travis.yml b/.travis.yml index 54ae74fd3c..34787669db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,12 @@ # compiler key (which we don't use anyway). This is worked around for now by # replacing the "compilers" with a build name prefixed by the no-op ":" # command. See: https://github.com/travis-ci/travis-ci/issues/4393 +# - sudo/dist/group are set so as to get Blue Box VMs, necessary for [loopback] +# IPv6 support + +sudo: required +dist: precise +group: legacy os: linux language: cpp @@ -52,7 +58,7 @@ install: before_script: - unset CC; unset CXX - mkdir -p depends/SDKs depends/sdk-sources - - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then wget $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -O depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi + - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS script: diff --git a/autogen.sh b/autogen.sh index 3e26a18305..46e36ff5b2 100755 --- a/autogen.sh +++ b/autogen.sh @@ -6,4 +6,6 @@ if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="`which glibtoolize 2>/dev/null`"; then LIBTOOLIZE="${GLIBTOOLIZE}" export LIBTOOLIZE fi +which autoreconf >/dev/null || \ + (echo "configuration failed, please install autoconf first" && exit 1) autoreconf --install --force --warnings=all diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index b366460e64..cedbddc578 100644 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -7,7 +7,7 @@ build_darwin_OTOOL: = $(shell xcrun -f otool) build_darwin_NM: = $(shell xcrun -f nm) build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) build_darwin_SHA256SUM = shasum -a 256 -build_darwin_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o +build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o #darwin host on darwin builder. overrides darwin host preferences. darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION) diff --git a/depends/builders/linux.mk b/depends/builders/linux.mk index 98d0e9de34..d6a304e4b4 100644 --- a/depends/builders/linux.mk +++ b/depends/builders/linux.mk @@ -1,2 +1,2 @@ build_linux_SHA256SUM = sha256sum -build_linux_DOWNLOAD = wget --timeout=$(DOWNLOAD_CONNECT_TIMEOUT) --tries=$(DOWNLOAD_RETRIES) -nv -O +build_linux_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index e7173fda08..7649c1183b 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -110,6 +110,7 @@ testScripts = [ testScriptsExt = [ 'bip65-cltv.py', 'bip65-cltv-p2p.py', + 'bip68-sequence.py', 'bipdersig-p2p.py', 'bipdersig.py', 'getblocktemplate_longpoll.py', diff --git a/src/Makefile.am b/src/Makefile.am index c4f7188971..fa7a78f330 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -430,6 +430,7 @@ endif # CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a +CLEANFILES += $(EXTRA_LIBRARIES) CLEANFILES += *.gcda *.gcno CLEANFILES += compat/*.gcda compat/*.gcno CLEANFILES += consensus/*.gcda consensus/*.gcno diff --git a/src/init.cpp b/src/init.cpp index 95235def59..048843a4c1 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -72,6 +72,8 @@ static const bool DEFAULT_REST_ENABLE = false; static const bool DEFAULT_DISABLE_SAFEMODE = false; static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; +static const char * const DEFAULT_WALLET_DAT = "wallet.dat"; + #if ENABLE_ZMQ static CZMQNotificationInterface* pzmqNotificationInterface = NULL; #endif @@ -368,9 +370,9 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy")); strUsage += HelpMessageOpt("-onlynet=<net>", _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)")); strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG)); - strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), 1)); + strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), DEFAULT_PEERBLOOMFILTERS)); if (showDebug) - strUsage += HelpMessageOpt("-enforcenodebloom", strprintf("Enforce minimum protocol version to limit use of bloom filters (default: %u)", 0)); + strUsage += HelpMessageOpt("-enforcenodebloom", strprintf("Enforce minimum protocol version to limit use of bloom filters (default: %u)", DEFAULT_ENFORCENODEBLOOM)); strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), Params(CBaseChainParams::MAIN).GetDefaultPort(), Params(CBaseChainParams::TESTNET).GetDefaultPort())); strUsage += HelpMessageOpt("-proxy=<ip:port>", _("Connect through SOCKS5 proxy")); strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), DEFAULT_PROXYRANDOMIZE)); @@ -408,7 +410,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); - strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); + strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + @@ -1025,7 +1027,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS); - std::string strWalletFile = GetArg("-wallet", "wallet.dat"); + std::string strWalletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); #endif // ENABLE_WALLET fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); @@ -1037,7 +1039,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // Option to startup with mocktime set (used for regression testing): SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op - if (GetBoolArg("-peerbloomfilters", true)) + if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) nLocalServices |= NODE_BLOOM; nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); diff --git a/src/main.cpp b/src/main.cpp index 23429ea2cc..babdff54ef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4374,7 +4374,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pfrom->nVersion >= NO_BLOOM_VERSION) { Misbehaving(pfrom->GetId(), 100); return false; - } else if (GetBoolArg("-enforcenodebloom", false)) { + } else if (GetBoolArg("-enforcenodebloom", DEFAULT_ENFORCENODEBLOOM)) { pfrom->fDisconnect = true; return false; } diff --git a/src/main.h b/src/main.h index b6f61ca991..5ba2be251c 100644 --- a/src/main.h +++ b/src/main.h @@ -121,6 +121,9 @@ static const bool DEFAULT_ENABLE_REPLACEMENT = true; /** Maximum number of headers to announce when relaying blocks with headers message.*/ static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; +static const bool DEFAULT_PEERBLOOMFILTERS = true; +static const bool DEFAULT_ENFORCENODEBLOOM = false; + struct BlockHasher { size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); } diff --git a/src/policy/policy.h b/src/policy/policy.h index aabeebb25d..4f9354e36f 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -40,6 +40,7 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS | SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY | + SCRIPT_VERIFY_CHECKSEQUENCEVERIFY | SCRIPT_VERIFY_LOW_S; /** For convenience, standard but not mandatory verify flags. */ diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 901f901f01..149a4f0156 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -373,7 +373,44 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un break; } - case OP_NOP1: case OP_NOP3: case OP_NOP4: case OP_NOP5: + case OP_CHECKSEQUENCEVERIFY: + { + if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) { + // not enabled; treat as a NOP3 + if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); + } + break; + } + + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + // nSequence, like nLockTime, is a 32-bit unsigned integer + // field. See the comment in CHECKLOCKTIMEVERIFY regarding + // 5-byte numeric operands. + const CScriptNum nSequence(stacktop(-1), fRequireMinimal, 5); + + // In the rare event that the argument may be < 0 due to + // some arithmetic being done first, you can always use + // 0 MAX CHECKSEQUENCEVERIFY. + if (nSequence < 0) + return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME); + + // To provide for future soft-fork extensibility, if the + // operand has the disabled lock-time flag set, + // CHECKSEQUENCEVERIFY behaves as a NOP. + if ((nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0) + break; + + // Compare the specified sequence number with the input. + if (!checker.CheckSequence(nSequence)) + return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME); + + break; + } + + case OP_NOP1: case OP_NOP4: case OP_NOP5: case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: { if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) @@ -1156,6 +1193,51 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con return true; } +bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) const +{ + // Relative lock times are supported by comparing the passed + // in operand to the sequence number of the input. + const int64_t txToSequence = (int64_t)txTo->vin[nIn].nSequence; + + // Fail if the transaction's version number is not set high + // enough to trigger BIP 68 rules. + if (static_cast<uint32_t>(txTo->nVersion) < 2) + return false; + + // Sequence numbers with their most significant bit set are not + // consensus constrained. Testing that the transaction's sequence + // number do not have this bit set prevents using this property + // to get around a CHECKSEQUENCEVERIFY check. + if (txToSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) + return false; + + // Mask off any bits that do not have consensus-enforced meaning + // before doing the integer comparisons + const uint32_t nLockTimeMask = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | CTxIn::SEQUENCE_LOCKTIME_MASK; + const int64_t txToSequenceMasked = txToSequence & nLockTimeMask; + const CScriptNum nSequenceMasked = nSequence & nLockTimeMask; + + // There are two kinds of nSequence: lock-by-blockheight + // and lock-by-blocktime, distinguished by whether + // nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG. + // + // We want to compare apples to apples, so fail the script + // unless the type of nSequenceMasked being tested is the same as + // the nSequenceMasked in the transaction. + if (!( + (txToSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) || + (txToSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) + )) { + return false; + } + + // Now that we know we're comparing apples-to-apples, the + // comparison is a simple numeric one. + if (nSequenceMasked > txToSequenceMasked) + return false; + + return true; +} bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) { diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 7b34547ffb..e5cb7290f2 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -81,6 +81,11 @@ enum // // See BIP65 for details. SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), + + // support CHECKSEQUENCEVERIFY opcode + // + // See BIP112 for details + SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), }; bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror); @@ -100,6 +105,11 @@ public: return false; } + virtual bool CheckSequence(const CScriptNum& nSequence) const + { + return false; + } + virtual ~BaseSignatureChecker() {} }; @@ -116,6 +126,7 @@ public: TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {} bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const; bool CheckLockTime(const CScriptNum& nLockTime) const; + bool CheckSequence(const CScriptNum& nSequence) const; }; class MutableTransactionSignatureChecker : public TransactionSignatureChecker diff --git a/src/script/script.h b/src/script/script.h index 6551eea30d..d2a68a07ba 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -165,6 +165,7 @@ enum opcodetype OP_CHECKLOCKTIMEVERIFY = 0xb1, OP_NOP2 = OP_CHECKLOCKTIMEVERIFY, OP_NOP3 = 0xb2, + OP_CHECKSEQUENCEVERIFY = OP_NOP3, OP_NOP4 = 0xb3, OP_NOP5 = 0xb4, OP_NOP6 = 0xb5, @@ -259,6 +260,11 @@ public: 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<int64_t>::min()); @@ -287,6 +293,12 @@ public: return *this; } + inline CScriptNum& operator&=( const int64_t& rhs) + { + m_value &= rhs; + return *this; + } + int getint() const { if (m_value > std::numeric_limits<int>::max()) diff --git a/src/script/script_error.h b/src/script/script_error.h index bb10b8a293..26df33932f 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -35,7 +35,7 @@ typedef enum ScriptError_t SCRIPT_ERR_INVALID_ALTSTACK_OPERATION, SCRIPT_ERR_UNBALANCED_CONDITIONAL, - /* OP_CHECKLOCKTIMEVERIFY */ + /* CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY */ SCRIPT_ERR_NEGATIVE_LOCKTIME, SCRIPT_ERR_UNSATISFIED_LOCKTIME, diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 9025841949..2d7d9b9585 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -201,5 +201,59 @@ [[["b1dbc81696c8a9c0fccd0693ab66d7c368dbc38c0def4e800685560ddd1b2132", 0, "DUP HASH160 0x14 0x4b3bd7eba3bc0284fd3007be7f3be275e94f5826 EQUALVERIFY CHECKSIG"]], "010000000132211bdd0d568506804eef0d8cc3db68c3d766ab9306cdfcc0a9c89616c8dbb1000000006c493045022100c7bb0faea0522e74ff220c20c022d2cb6033f8d167fb89e75a50e237a35fd6d202203064713491b1f8ad5f79e623d0219ad32510bfaa1009ab30cbee77b59317d6e30001210237af13eb2d84e4545af287b919c2282019c9691cc509e78e196a9d8274ed1be0ffffffff0100000000000000001976a914f1b3ed2eda9a2ebe5a9374f692877cdf87c0f95b88ac00000000", "P2SH,DERSIG"], +["CHECKSEQUENCEVERIFY tests"], + +["By-height locks, with argument just beyond txin.nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000feff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["By-time locks, with argument just beyond txin.nSequence (but within numerical boundries)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194305 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000feff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument missing"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument negative with by-blockheight txin.nSequence=0"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument negative with by-blocktime txin.nSequence=CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument/tx height/time mismatch, both versions"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Failure due to failing CHECKSEQUENCEVERIFY in scriptSig"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"02000000010001000000000000000000000000000000000000000000000000000000000000000000000251b2000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Failure due to failing CHECKSEQUENCEVERIFY in redeemScript"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7c17aff532f22beb54069942f9bf567a66133eaf EQUAL"]], +"0200000001000100000000000000000000000000000000000000000000000000000000000000000000030251b2000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Failure due to insufficient tx.nVersion (<2)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP3 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 76d29bcf26..717ad19549 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -233,5 +233,89 @@ [[["b1dbc81696c8a9c0fccd0693ab66d7c368dbc38c0def4e800685560ddd1b2132", 0, "DUP HASH160 0x14 0x4b3bd7eba3bc0284fd3007be7f3be275e94f5826 EQUALVERIFY CHECKSIG"]], "010000000132211bdd0d568506804eef0d8cc3db68c3d766ab9306cdfcc0a9c89616c8dbb1000000006c493045022100c7bb0faea0522e74ff220c20c022d2cb6033f8d167fb89e75a50e237a35fd6d202203064713491b1f8ad5f79e623d0219ad32510bfaa1009ab30cbee77b59317d6e30001210237af13eb2d84e4545af287b919c2282019c9691cc509e78e196a9d8274ed1be0ffffffff0100000000000000001976a914f1b3ed2eda9a2ebe5a9374f692877cdf87c0f95b88ac00000000", "P2SH"], +["CHECKSEQUENCEVERIFY tests"], + +["By-height locks, with argument == 0 and == txin.nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["By-time locks, with argument == 0 and == txin.nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Upper sequence with upper sequence is fine"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000800100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000800100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument 2^31 with various nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument 2^32-1 with various nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument 3<<31 with various nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["5 byte non-minimally-encoded operandss are valid"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["The argument can be calculated rather than created directly by a PUSHDATA"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194303 1ADD NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 1SUB NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["An ADD producing a 5-byte result that sets CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 65536 NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 4259840 ADD NOP3 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Valid CHECKSEQUENCEVERIFY in scriptSig"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"02000000010001000000000000000000000000000000000000000000000000000000000000000000000251b2010000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Valid CHECKSEQUENCEVERIFY in redeemScript"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7c17aff532f22beb54069942f9bf567a66133eaf EQUAL"]], +"0200000001000100000000000000000000000000000000000000000000000000000000000000000000030251b2010000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index c27f194b55..d9195bf345 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -44,7 +44,8 @@ static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of (string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY) (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) (string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK) - (string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY); + (string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) + (string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY); unsigned int ParseScriptFlags(string strFlags) { diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 01bc2032d0..43e8ae9b36 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -60,6 +60,10 @@ BOOST_AUTO_TEST_CASE(util_ParseHex) result = ParseHex("12 34 56 78"); BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78); + // Leading space must be supported (used in CDBEnv::Salvage) + result = ParseHex(" 89 34 56 78"); + BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78); + // Stop parsing at invalid value result = ParseHex("1234 invalid 1234"); BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34); diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 50b0f40a6a..6af5413a9e 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -193,9 +193,9 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C // Format of bdb dump is ascii lines: // header lines... // HEADER=END - // hexadecimal key - // hexadecimal value - // ... repeated + // hexadecimal key + // hexadecimal value + // ... repeated // DATA=END string strLine; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 857a3a77e2..34ad5a46f7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1245,7 +1245,7 @@ UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) "\nList balances by receiving address.\n" "\nArguments:\n" "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n" - "2. includeempty (numeric, optional, default=false) Whether to include addresses that haven't received any payments.\n" + "2. includeempty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n" "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n" "\nResult:\n" @@ -1283,7 +1283,7 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) "\nDEPRECATED. List balances by account.\n" "\nArguments:\n" "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n" - "2. includeempty (boolean, optional, default=false) Whether to include accounts that haven't received any payments.\n" + "2. includeempty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n" "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n" "\nResult:\n" |