aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdepends/config.guess5
-rwxr-xr-xdepends/config.sub8
-rw-r--r--depends/packages/boost.mk6
-rw-r--r--depends/packages/miniupnpc.mk6
-rw-r--r--depends/packages/native_ccache.mk4
-rw-r--r--depends/packages/zeromq.mk4
-rw-r--r--doc/release-notes.md14
-rwxr-xr-xqa/pull-tester/rpc-tests.py7
-rwxr-xr-xqa/rpc-tests/bip65-cltv-p2p.py4
-rwxr-xr-xqa/rpc-tests/decodescript.py4
-rwxr-xr-xqa/rpc-tests/mempool_limit.py67
-rwxr-xr-xqa/rpc-tests/mempool_packages.py24
-rwxr-xr-xqa/rpc-tests/p2p-fullblocktest.py157
-rwxr-xr-xqa/rpc-tests/prioritise_transaction.py91
-rwxr-xr-xqa/rpc-tests/replace-by-fee.py80
-rwxr-xr-xqa/rpc-tests/test_framework/mininode.py1
-rw-r--r--qa/rpc-tests/test_framework/script.py8
-rw-r--r--qa/rpc-tests/test_framework/util.py46
-rw-r--r--src/chainparams.cpp1
-rw-r--r--src/main.cpp57
-rw-r--r--src/main.h2
-rw-r--r--src/qt/locale/bitcoin_en.ts2
-rw-r--r--src/qt/utilitydialog.cpp2
-rw-r--r--src/rpcblockchain.cpp4
-rw-r--r--src/script/script.cpp2
-rw-r--r--src/script/script.h4
-rw-r--r--src/test/data/script_invalid.json6
-rw-r--r--src/test/data/script_valid.json6
-rw-r--r--src/test/data/tx_invalid.json32
-rw-r--r--src/test/data/tx_valid.json20
-rw-r--r--src/test/script_tests.cpp8
-rw-r--r--src/torcontrol.cpp2
-rw-r--r--src/txmempool.cpp53
-rw-r--r--src/txmempool.h43
34 files changed, 559 insertions, 221 deletions
diff --git a/depends/config.guess b/depends/config.guess
index b3f905370a..fba6e87a0f 100755
--- a/depends/config.guess
+++ b/depends/config.guess
@@ -2,7 +2,7 @@
# Attempt to guess a canonical system name.
# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2015-10-21'
+timestamp='2015-11-19'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -1393,6 +1393,9 @@ EOF
x86_64:VMkernel:*:*)
echo ${UNAME_MACHINE}-unknown-esx
exit ;;
+ amd64:Isilon\ OneFS:*:*)
+ echo x86_64-unknown-onefs
+ exit ;;
esac
cat >&2 <<EOF
diff --git a/depends/config.sub b/depends/config.sub
index 1acc966a33..ea8747d30f 100755
--- a/depends/config.sub
+++ b/depends/config.sub
@@ -2,7 +2,7 @@
# Configuration validation subroutine script.
# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2015-08-20'
+timestamp='2015-11-22'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -53,8 +53,7 @@ timestamp='2015-08-20'
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name.
@@ -1399,7 +1398,8 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+ | -onefs* | -tirtos*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk
index d27a701344..215c694b6b 100644
--- a/depends/packages/boost.mk
+++ b/depends/packages/boost.mk
@@ -1,8 +1,8 @@
package=boost
-$(package)_version=1_58_0
-$(package)_download_path=http://sourceforge.net/projects/boost/files/boost/1.58.0
+$(package)_version=1_59_0
+$(package)_download_path=http://sourceforge.net/projects/boost/files/boost/1.59.0
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
-$(package)_sha256_hash=fdfc204fc33ec79c99b9a74944c3e54bd78be4f7f15e260c0e2700a36dc7d3e5
+$(package)_sha256_hash=727a932322d94287b62abb1bd2d41723eec4356a7728909e38adb65ca25241ca
define $(package)_set_vars
$(package)_config_opts_release=variant=release
diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk
index 77bae10c79..3d5a6df974 100644
--- a/depends/packages/miniupnpc.mk
+++ b/depends/packages/miniupnpc.mk
@@ -1,12 +1,12 @@
package=miniupnpc
-$(package)_version=1.9.20151008
+$(package)_version=1.9.20151026
$(package)_download_path=http://miniupnp.free.fr/files
$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=e444ac3b587ce82709c4d0cfca1fe71f44f9fc433e9f946b12b9e1bfe667a633
+$(package)_sha256_hash=f3cf9a5a31588a917d4d9237e5bc50f84d00c5aa48e27ed50d9b88dfa6a25d47
define $(package)_set_vars
$(package)_build_opts=CC="$($(package)_cc)"
-$(package)_build_opts_darwin=OS=Darwin
+$(package)_build_opts_darwin=OS=Darwin LIBTOOL="$($(package)_libtool)"
$(package)_build_opts_mingw32=-f Makefile.mingw
$(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)"
endef
diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk
index 317674f795..cc76f9a794 100644
--- a/depends/packages/native_ccache.mk
+++ b/depends/packages/native_ccache.mk
@@ -1,8 +1,8 @@
package=native_ccache
-$(package)_version=3.2.3
+$(package)_version=3.2.4
$(package)_download_path=http://samba.org/ftp/ccache
$(package)_file_name=ccache-$($(package)_version).tar.bz2
-$(package)_sha256_hash=b07165d4949d107d17f2f84b90b52953617bf1abbf249d5cc20636f43337c98c
+$(package)_sha256_hash=ffeb967edb549e67da0bd5f44f729a2022de9fdde65dfd80d2a7204d7f75332e
define $(package)_set_vars
$(package)_config_opts=
diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk
index 24e8e5f1c9..7b866e9c0f 100644
--- a/depends/packages/zeromq.mk
+++ b/depends/packages/zeromq.mk
@@ -1,8 +1,8 @@
package=zeromq
-$(package)_version=4.0.4
+$(package)_version=4.0.7
$(package)_download_path=http://download.zeromq.org
$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=1ef71d46e94f33e27dd5a1661ed626cd39be4d2d6967792a275040e34457d399
+$(package)_sha256_hash=e00b2967e074990d0538361cc79084a0a92892df2c6e7585da34e4c61ee47b03
define $(package)_set_vars
$(package)_config_opts=--without-documentation --disable-shared
diff --git a/doc/release-notes.md b/doc/release-notes.md
index 8bb842ddb8..801b684e6b 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -18,6 +18,20 @@ git merge commit are mentioned.
### RPC and REST
+Asm script outputs now contain OP_CHECKLOCKTIMEVERIFY in place of OP_NOP2
+-------------------------------------------------------------------------
+
+OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP
+65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki)
+
+The following outputs are affected by this change:
+- RPC `getrawtransaction` (in verbose mode)
+- RPC `decoderawtransaction`
+- RPC `decodescript`
+- REST `/rest/tx/` (JSON format)
+- REST `/rest/block/` (JSON format when including extended tx details)
+- `bitcoin-tx -json`
+
### Configuration and command-line options
### Block and transaction handling
diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py
index 0cb721b033..44d7d71759 100755
--- a/qa/pull-tester/rpc-tests.py
+++ b/qa/pull-tester/rpc-tests.py
@@ -62,8 +62,10 @@ for arg in sys.argv[1:]:
#Set env vars
buildDir = BUILDDIR
-os.environ["BITCOIND"] = buildDir + '/src/bitcoind' + EXEEXT
-os.environ["BITCOINCLI"] = buildDir + '/src/bitcoin-cli' + EXEEXT
+if "BITCOIND" not in os.environ:
+ os.environ["BITCOIND"] = buildDir + '/src/bitcoind' + EXEEXT
+if "BITCOINCLI" not in os.environ:
+ os.environ["BITCOINCLI"] = buildDir + '/src/bitcoin-cli' + EXEEXT
#Disable Windows tests by default
if EXEEXT == ".exe" and "-win" not in opts:
@@ -83,6 +85,7 @@ testScripts = [
'rest.py',
'mempool_spendcoinbase.py',
'mempool_reorg.py',
+ 'mempool_limit.py',
'httpbasics.py',
'multi_rpc.py',
'zapwallettxes.py',
diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py
index 9ca5c69f16..5bb41df1ad 100755
--- a/qa/rpc-tests/bip65-cltv-p2p.py
+++ b/qa/rpc-tests/bip65-cltv-p2p.py
@@ -9,7 +9,7 @@ from test_framework.util import *
from test_framework.mininode import CTransaction, NetworkThread
from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager
-from test_framework.script import CScript, OP_1NEGATE, OP_NOP2, OP_DROP
+from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP
from binascii import hexlify, unhexlify
import cStringIO
import time
@@ -19,7 +19,7 @@ def cltv_invalidate(tx):
Prepends -1 CLTV DROP in the scriptSig itself.
'''
- tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_NOP2, OP_DROP] +
+ tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP] +
list(CScript(tx.vin[0].scriptSig)))
'''
diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py
index 4bca623380..490808d49d 100755
--- a/qa/rpc-tests/decodescript.py
+++ b/qa/rpc-tests/decodescript.py
@@ -102,13 +102,13 @@ class DecodeScriptTest(BitcoinTestFramework):
# OP_IF
# <receiver-pubkey> OP_CHECKSIGVERIFY
# OP_ELSE
- # <lock-until> OP_NOP2 OP_DROP
+ # <lock-until> OP_CHECKLOCKTIMEVERIFY OP_DROP
# OP_ENDIF
# <sender-pubkey> OP_CHECKSIG
#
# lock until block 500,000
rpc_result = self.nodes[0].decodescript('63' + push_public_key + 'ad670320a107b17568' + push_public_key + 'ac')
- assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_NOP2 OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm'])
+ assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm'])
def decoderawtransaction_asm_sighashtype(self):
"""Tests decoding scripts via RPC command "decoderawtransaction".
diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py
new file mode 100755
index 0000000000..48a2ea294a
--- /dev/null
+++ b/qa/rpc-tests/mempool_limit.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014-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.
+
+# Test mempool limiting together/eviction with the wallet
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+class MempoolLimitTest(BitcoinTestFramework):
+
+ def __init__(self):
+ # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create
+ # So we have big transactions (and therefore can't fit very many into each block)
+ # create one script_pubkey
+ script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes
+ for i in xrange (512):
+ script_pubkey = script_pubkey + "01"
+ # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change
+ self.txouts = "81"
+ for k in xrange(128):
+ # add txout value
+ self.txouts = self.txouts + "0000000000000000"
+ # add length of script_pubkey
+ self.txouts = self.txouts + "fd0402"
+ # add script_pubkey
+ self.txouts = self.txouts + script_pubkey
+
+ def setup_network(self):
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, ["-maxmempool=5", "-spendzeroconfchange=0", "-debug"]))
+ self.is_network_split = False
+ self.sync_all()
+ self.relayfee = self.nodes[0].getnetworkinfo()['relayfee']
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 2)
+
+ def run_test(self):
+ txids = []
+ utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 90)
+
+ #create a mempool tx that will be evicted
+ us0 = utxos.pop()
+ inputs = [{ "txid" : us0["txid"], "vout" : us0["vout"]}]
+ outputs = {self.nodes[0].getnewaddress() : 0.0001}
+ tx = self.nodes[0].createrawtransaction(inputs, outputs)
+ txF = self.nodes[0].fundrawtransaction(tx)
+ txFS = self.nodes[0].signrawtransaction(txF['hex'])
+ txid = self.nodes[0].sendrawtransaction(txFS['hex'])
+ self.nodes[0].lockunspent(True, [us0])
+
+ relayfee = self.nodes[0].getnetworkinfo()['relayfee']
+ base_fee = relayfee*100
+ for i in xrange (4):
+ txids.append([])
+ txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee)
+
+ # by now, the tx should be evicted, check confirmation state
+ assert(txid not in self.nodes[0].getrawmempool())
+ txdata = self.nodes[0].gettransaction(txid);
+ assert(txdata['confirmations'] == 0) #confirmation should still be 0
+
+if __name__ == '__main__':
+ MempoolLimitTest().main()
diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py
index 34b316a6a3..063308d394 100755
--- a/qa/rpc-tests/mempool_packages.py
+++ b/qa/rpc-tests/mempool_packages.py
@@ -64,17 +64,41 @@ class MempoolPackagesTest(BitcoinTestFramework):
for x in reversed(chain):
assert_equal(mempool[x]['descendantcount'], descendant_count)
descendant_fees += mempool[x]['fee']
+ assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee'])
assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees)
descendant_size += mempool[x]['size']
assert_equal(mempool[x]['descendantsize'], descendant_size)
descendant_count += 1
+ # Check that descendant modified fees includes fee deltas from
+ # prioritisetransaction
+ self.nodes[0].prioritisetransaction(chain[-1], 0, 1000)
+ mempool = self.nodes[0].getrawmempool(True)
+
+ descendant_fees = 0
+ for x in reversed(chain):
+ descendant_fees += mempool[x]['fee']
+ assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees+1000)
+
# Adding one more transaction on to the chain should fail.
try:
self.chain_transaction(self.nodes[0], txid, vout, value, fee, 1)
except JSONRPCException as e:
print "too-long-ancestor-chain successfully rejected"
+ # Check that prioritising a tx before it's added to the mempool works
+ self.nodes[0].generate(1)
+ self.nodes[0].prioritisetransaction(chain[-1], 0, 2000)
+ self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
+ mempool = self.nodes[0].getrawmempool(True)
+
+ descendant_fees = 0
+ for x in reversed(chain):
+ descendant_fees += mempool[x]['fee']
+ if (x == chain[-1]):
+ assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']+satoshi_round(0.00002))
+ assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees+2000)
+
# TODO: check that node1's mempool is as expected
# TODO: test ancestor size limits
diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py
index 9555940cec..a6525e6793 100755
--- a/qa/rpc-tests/p2p-fullblocktest.py
+++ b/qa/rpc-tests/p2p-fullblocktest.py
@@ -7,7 +7,7 @@
from test_framework.test_framework import ComparisonTestFramework
from test_framework.util import *
-from test_framework.comptool import TestManager, TestInstance
+from test_framework.comptool import TestManager, TestInstance, RejectResult
from test_framework.mininode import *
from test_framework.blocktools import *
import logging
@@ -15,7 +15,7 @@ import copy
import time
import numbers
from test_framework.key import CECKey
-from test_framework.script import CScript, CScriptOp, SignatureHash, SIGHASH_ALL, OP_TRUE
+from test_framework.script import CScript, CScriptOp, SignatureHash, SIGHASH_ALL, OP_TRUE, OP_FALSE
class PreviousSpendableOutput(object):
def __init__(self, tx = CTransaction(), n = -1):
@@ -122,13 +122,29 @@ class FullBlockTest(ComparisonTestFramework):
return TestInstance([[self.tip, True]])
# returns a test case that asserts that the current tip was rejected
- def rejected():
- return TestInstance([[self.tip, False]])
+ def rejected(reject = None):
+ if reject is None:
+ return TestInstance([[self.tip, False]])
+ else:
+ return TestInstance([[self.tip, reject]])
# move the tip back to a previous block
def tip(number):
self.tip = self.blocks[number]
+ # add transactions to a block produced by next_block
+ def update_block(block_number, new_transactions):
+ block = self.blocks[block_number]
+ old_hash = block.sha256
+ self.add_transactions_to_block(block, new_transactions)
+ block.solve()
+ # Update the internal state just like in next_block
+ self.tip = block
+ self.block_heights[block.sha256] = self.block_heights[old_hash]
+ del self.block_heights[old_hash]
+ self.blocks[block_number] = block
+ return block
+
# creates a new block and advances the tip to that block
block = self.next_block
@@ -141,14 +157,15 @@ class FullBlockTest(ComparisonTestFramework):
# Now we need that block to mature so we can spend the coinbase.
test = TestInstance(sync_every_block=False)
- for i in range(100):
+ for i in range(99):
block(1000 + i)
test.blocks_and_transactions.append([self.tip, True])
save_spendable_output()
yield test
- # Start by bulding a couple of blocks on top (which output is spent is in parentheses):
+ # Start by building a couple of blocks on top (which output is spent is
+ # in parentheses):
# genesis -> b1 (0) -> b2 (1)
out0 = get_spendable_output()
block(1, spend=out0)
@@ -156,8 +173,7 @@ class FullBlockTest(ComparisonTestFramework):
yield accepted()
out1 = get_spendable_output()
- block(2, spend=out1)
- # Inv again, then deliver twice (shouldn't break anything).
+ b2 = block(2, spend=out1)
yield accepted()
@@ -168,8 +184,8 @@ class FullBlockTest(ComparisonTestFramework):
#
# Nothing should happen at this point. We saw b2 first so it takes priority.
tip(1)
- block(3, spend=out1)
- # Deliver twice (should still not break anything)
+ b3 = block(3, spend=out1)
+ txout_b3 = PreviousSpendableOutput(b3.vtx[1], 1)
yield rejected()
@@ -214,7 +230,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b3 (1) -> b4 (2)
tip(6)
block(9, spend=out4, additional_coinbase_value=1)
- yield rejected()
+ yield rejected(RejectResult(16, 'bad-cb-amount'))
# Create a fork that ends in a block with too much fee (the one that causes the reorg)
@@ -226,7 +242,7 @@ class FullBlockTest(ComparisonTestFramework):
yield rejected()
block(11, spend=out4, additional_coinbase_value=1)
- yield rejected()
+ yield rejected(RejectResult(16, 'bad-cb-amount'))
# Try again, but with a valid fork first
@@ -252,6 +268,10 @@ class FullBlockTest(ComparisonTestFramework):
yield TestInstance([[b12, True, b13.sha256]]) # New tip should be b13.
+ # Add a block with MAX_BLOCK_SIGOPS and one with one more sigop
+ # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
+ # \-> b12 (3) -> b13 (4) -> b15 (5) -> b16 (6)
+ # \-> b3 (1) -> b4 (2)
# Test that a block with a lot of checksigs is okay
lots_of_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50 - 1))
@@ -264,8 +284,121 @@ class FullBlockTest(ComparisonTestFramework):
out6 = get_spendable_output()
too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50))
block(16, spend=out6, script=too_many_checksigs)
+ yield rejected(RejectResult(16, 'bad-blk-sigops'))
+
+
+ # Attempt to spend a transaction created on a different fork
+ # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
+ # \-> b12 (3) -> b13 (4) -> b15 (5) -> b17 (b3.vtx[1])
+ # \-> b3 (1) -> b4 (2)
+ tip(15)
+ block(17, spend=txout_b3)
+ yield rejected(RejectResult(16, 'bad-txns-inputs-missingorspent'))
+
+ # Attempt to spend a transaction created on a different fork (on a fork this time)
+ # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
+ # \-> b12 (3) -> b13 (4) -> b15 (5)
+ # \-> b18 (b3.vtx[1]) -> b19 (6)
+ # \-> b3 (1) -> b4 (2)
+ tip(13)
+ block(18, spend=txout_b3)
+ yield rejected()
+
+ block(19, spend=out6)
yield rejected()
+ # Attempt to spend a coinbase at depth too low
+ # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
+ # \-> b12 (3) -> b13 (4) -> b15 (5) -> b20 (7)
+ # \-> b3 (1) -> b4 (2)
+ tip(15)
+ out7 = get_spendable_output()
+ block(20, spend=out7)
+ yield rejected(RejectResult(16, 'bad-txns-premature-spend-of-coinbase'))
+
+ # Attempt to spend a coinbase at depth too low (on a fork this time)
+ # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
+ # \-> b12 (3) -> b13 (4) -> b15 (5)
+ # \-> b21 (6) -> b22 (5)
+ # \-> b3 (1) -> b4 (2)
+ tip(13)
+ block(21, spend=out6)
+ yield rejected()
+
+ block(22, spend=out5)
+ yield rejected()
+
+ # Create a block on either side of MAX_BLOCK_SIZE and make sure its accepted/rejected
+ # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
+ # \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6)
+ # \-> b24 (6) -> b25 (7)
+ # \-> b3 (1) -> b4 (2)
+ tip(15)
+ b23 = block(23, spend=out6)
+ old_hash = b23.sha256
+ tx = CTransaction()
+ script_length = MAX_BLOCK_SIZE - len(b23.serialize()) - 69
+ script_output = CScript([chr(0)*script_length])
+ tx.vout.append(CTxOut(0, script_output))
+ tx.vin.append(CTxIn(COutPoint(b23.vtx[1].sha256, 1)))
+ b23 = update_block(23, [tx])
+ # Make sure the math above worked out to produce a max-sized block
+ assert_equal(len(b23.serialize()), MAX_BLOCK_SIZE)
+ yield accepted()
+
+ # Make the next block one byte bigger and check that it fails
+ tip(15)
+ b24 = block(24, spend=out6)
+ script_length = MAX_BLOCK_SIZE - len(b24.serialize()) - 69
+ script_output = CScript([chr(0)*(script_length+1)])
+ tx.vout = [CTxOut(0, script_output)]
+ b24 = update_block(24, [tx])
+ assert_equal(len(b24.serialize()), MAX_BLOCK_SIZE+1)
+ yield rejected(RejectResult(16, 'bad-blk-length'))
+
+ b25 = block(25, spend=out7)
+ yield rejected()
+
+ # Create blocks with a coinbase input script size out of range
+ # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
+ # \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) -> b30 (7)
+ # \-> ... (6) -> ... (7)
+ # \-> b3 (1) -> b4 (2)
+ tip(15)
+ b26 = block(26, spend=out6)
+ b26.vtx[0].vin[0].scriptSig = chr(0)
+ b26.vtx[0].rehash()
+ # update_block causes the merkle root to get updated, even with no new
+ # transactions, and updates the required state.
+ b26 = update_block(26, [])
+ yield rejected(RejectResult(16, 'bad-cb-length'))
+
+ # Extend the b26 chain to make sure bitcoind isn't accepting b26
+ b27 = block(27, spend=out7)
+ yield rejected()
+
+ # Now try a too-large-coinbase script
+ tip(15)
+ b28 = block(28, spend=out6)
+ b28.vtx[0].vin[0].scriptSig = chr(0)*101
+ b28.vtx[0].rehash()
+ b28 = update_block(28, [])
+ yield rejected(RejectResult(16, 'bad-cb-length'))
+
+ # Extend the b28 chain to make sure bitcoind isn't accepted b28
+ b29 = block(29, spend=out7)
+ # TODO: Should get a reject message back with "bad-prevblk", except
+ # there's a bug that prevents this from being detected. Just note
+ # failure for now, and add the reject result later.
+ yield rejected()
+
+ # b30 has a max-sized coinbase scriptSig.
+ tip(23)
+ b30 = block(30)
+ b30.vtx[0].vin[0].scriptSig = chr(0)*100
+ b30.vtx[0].rehash()
+ b30 = update_block(30, [])
+ yield accepted()
if __name__ == '__main__':
diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py
index f376ceee5e..c58ac58863 100755
--- a/qa/rpc-tests/prioritise_transaction.py
+++ b/qa/rpc-tests/prioritise_transaction.py
@@ -42,62 +42,15 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-printpriority=1"]))
self.relayfee = self.nodes[0].getnetworkinfo()['relayfee']
- def create_confirmed_utxos(self, count):
- self.nodes[0].generate(int(0.5*count)+101)
- utxos = self.nodes[0].listunspent()
- iterations = count - len(utxos)
- addr1 = self.nodes[0].getnewaddress()
- addr2 = self.nodes[0].getnewaddress()
- if iterations <= 0:
- return utxos
- for i in xrange(iterations):
- t = utxos.pop()
- fee = self.relayfee
- inputs = []
- inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
- outputs = {}
- send_value = t['amount'] - fee
- outputs[addr1] = satoshi_round(send_value/2)
- outputs[addr2] = satoshi_round(send_value/2)
- raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
- signed_tx = self.nodes[0].signrawtransaction(raw_tx)["hex"]
- txid = self.nodes[0].sendrawtransaction(signed_tx)
-
- while (self.nodes[0].getmempoolinfo()['size'] > 0):
- self.nodes[0].generate(1)
-
- utxos = self.nodes[0].listunspent()
- assert(len(utxos) >= count)
- return utxos
-
- def create_lots_of_big_transactions(self, utxos, fee):
- addr = self.nodes[0].getnewaddress()
- txids = []
- for i in xrange(len(utxos)):
- t = utxos.pop()
- inputs = []
- inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
- outputs = {}
- send_value = t['amount'] - fee
- outputs[addr] = satoshi_round(send_value)
- rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
- newtx = rawtx[0:92]
- newtx = newtx + self.txouts
- newtx = newtx + rawtx[94:]
- signresult = self.nodes[0].signrawtransaction(newtx, None, None, "NONE")
- txid = self.nodes[0].sendrawtransaction(signresult["hex"], True)
- txids.append(txid)
- return txids
-
def run_test(self):
- utxos = self.create_confirmed_utxos(90)
+ utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 90)
base_fee = self.relayfee*100 # our transactions are smaller than 100kb
txids = []
# Create 3 batches of transactions at 3 different fee rate levels
for i in xrange(3):
txids.append([])
- txids[i] = self.create_lots_of_big_transactions(utxos[30*i:30*i+30], (i+1)*base_fee)
+ txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee)
# add a fee delta to something in the cheapest bucket and make sure it gets mined
# also check that a different entry in the cheapest bucket is NOT mined (lower
@@ -143,5 +96,45 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
if (x != high_fee_tx):
assert(x not in mempool)
+ # Create a free, low priority transaction. Should be rejected.
+ utxo_list = self.nodes[0].listunspent()
+ assert(len(utxo_list) > 0)
+ utxo = utxo_list[0]
+
+ inputs = []
+ outputs = {}
+ inputs.append({"txid" : utxo["txid"], "vout" : utxo["vout"]})
+ outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee
+ raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
+ tx_hex = self.nodes[0].signrawtransaction(raw_tx)["hex"]
+ txid = self.nodes[0].sendrawtransaction(tx_hex)
+
+ # A tx that spends an in-mempool tx has 0 priority, so we can use it to
+ # test the effect of using prioritise transaction for mempool acceptance
+ inputs = []
+ inputs.append({"txid": txid, "vout": 0})
+ outputs = {}
+ outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee
+ raw_tx2 = self.nodes[0].createrawtransaction(inputs, outputs)
+ tx2_hex = self.nodes[0].signrawtransaction(raw_tx2)["hex"]
+ tx2_id = self.nodes[0].decoderawtransaction(tx2_hex)["txid"]
+
+ try:
+ self.nodes[0].sendrawtransaction(tx2_hex)
+ except JSONRPCException as exp:
+ assert_equal(exp.error['code'], -26) # insufficient fee
+ assert(tx2_id not in self.nodes[0].getrawmempool())
+ else:
+ assert(False)
+
+ # This is a less than 1000-byte transaction, so just set the fee
+ # to be the minimum for a 1000 byte transaction and check that it is
+ # accepted.
+ self.nodes[0].prioritisetransaction(tx2_id, 0, int(self.relayfee*COIN))
+
+ print "Assert that prioritised free transaction is accepted to mempool"
+ assert_equal(self.nodes[0].sendrawtransaction(tx2_hex), tx2_id)
+ assert(tx2_id in self.nodes[0].getrawmempool())
+
if __name__ == '__main__':
PrioritiseTransactionTest().main()
diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py
index 6e9e0b304c..734db33b51 100755
--- a/qa/rpc-tests/replace-by-fee.py
+++ b/qa/rpc-tests/replace-by-fee.py
@@ -63,8 +63,14 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])):
# If requested, ensure txouts are confirmed.
if confirmed:
- while len(node.getrawmempool()):
+ mempool_size = len(node.getrawmempool())
+ while mempool_size > 0:
node.generate(1)
+ new_size = len(node.getrawmempool())
+ # Error out if we have something stuck in the mempool, as this
+ # would likely be a bug.
+ assert(new_size < mempool_size)
+ mempool_size = new_size
return COutPoint(int(txid, 16), 0)
@@ -72,7 +78,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def setup_network(self):
self.nodes = []
- self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000",
+ self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", "-debug",
"-relaypriority=0", "-whitelist=127.0.0.1",
"-limitancestorcount=50",
"-limitancestorsize=101",
@@ -108,6 +114,9 @@ class ReplaceByFeeTest(BitcoinTestFramework):
print "Running test opt-in..."
self.test_opt_in()
+ print "Running test prioritised transactions..."
+ self.test_prioritised_transactions()
+
print "Passed\n"
def test_simple_doublespend(self):
@@ -513,5 +522,72 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# but make sure it is accepted anyway
self.nodes[0].sendrawtransaction(tx3c_hex, True)
+ def test_prioritised_transactions(self):
+ # Ensure that fee deltas used via prioritisetransaction are
+ # correctly used by replacement logic
+
+ # 1. Check that feeperkb uses modified fees
+ tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
+
+ tx1a = CTransaction()
+ tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
+ tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))]
+ tx1a_hex = txToHex(tx1a)
+ tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)
+
+ # Higher fee, but the actual fee per KB is much lower.
+ tx1b = CTransaction()
+ tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
+ tx1b.vout = [CTxOut(0.001*COIN, CScript([b'a'*740000]))]
+ tx1b_hex = txToHex(tx1b)
+
+ # Verify tx1b cannot replace tx1a.
+ try:
+ tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
+ except JSONRPCException as exp:
+ assert_equal(exp.error['code'], -26)
+ else:
+ assert(False)
+
+ # Use prioritisetransaction to set tx1a's fee to 0.
+ self.nodes[0].prioritisetransaction(tx1a_txid, 0, int(-0.1*COIN))
+
+ # Now tx1b should be able to replace tx1a
+ tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
+
+ assert(tx1b_txid in self.nodes[0].getrawmempool())
+
+ # 2. Check that absolute fee checks use modified fee.
+ tx1_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
+
+ tx2a = CTransaction()
+ tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0)]
+ tx2a.vout = [CTxOut(1*COIN, CScript([b'a']))]
+ tx2a_hex = txToHex(tx2a)
+ tx2a_txid = self.nodes[0].sendrawtransaction(tx2a_hex, True)
+
+ # Lower fee, but we'll prioritise it
+ tx2b = CTransaction()
+ tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)]
+ tx2b.vout = [CTxOut(1.01*COIN, CScript([b'a']))]
+ tx2b.rehash()
+ tx2b_hex = txToHex(tx2b)
+
+ # Verify tx2b cannot replace tx2a.
+ try:
+ tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True)
+ except JSONRPCException as exp:
+ assert_equal(exp.error['code'], -26)
+ else:
+ assert(False)
+
+ # Now prioritise tx2b to have a higher modified fee
+ self.nodes[0].prioritisetransaction(tx2b.hash, 0, int(0.1*COIN))
+
+ # tx2b should now be accepted
+ tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True)
+
+ assert(tx2b_txid in self.nodes[0].getrawmempool())
+
if __name__ == '__main__':
ReplaceByFeeTest().main()
diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py
index 9d0fb713a1..8e49b56565 100755
--- a/qa/rpc-tests/test_framework/mininode.py
+++ b/qa/rpc-tests/test_framework/mininode.py
@@ -36,6 +36,7 @@ MY_VERSION = 60001 # past bip-31 for ping/pong
MY_SUBVERSION = "/python-mininode-tester:0.0.1/"
MAX_INV_SZ = 50000
+MAX_BLOCK_SIZE = 1000000
# Keep our own socket map for asyncore, so that we can track disconnects
# ourselves (to workaround an issue with closing an asyncore socket when
diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py
index 0a78cf6fb1..0088876028 100644
--- a/qa/rpc-tests/test_framework/script.py
+++ b/qa/rpc-tests/test_framework/script.py
@@ -226,7 +226,7 @@ OP_CHECKMULTISIGVERIFY = CScriptOp(0xaf)
# expansion
OP_NOP1 = CScriptOp(0xb0)
-OP_NOP2 = CScriptOp(0xb1)
+OP_CHECKLOCKTIMEVERIFY = CScriptOp(0xb1)
OP_NOP3 = CScriptOp(0xb2)
OP_NOP4 = CScriptOp(0xb3)
OP_NOP5 = CScriptOp(0xb4)
@@ -353,7 +353,7 @@ VALID_OPCODES = {
OP_CHECKMULTISIGVERIFY,
OP_NOP1,
- OP_NOP2,
+ OP_CHECKLOCKTIMEVERIFY,
OP_NOP3,
OP_NOP4,
OP_NOP5,
@@ -472,7 +472,7 @@ OPCODE_NAMES.update({
OP_CHECKMULTISIG : 'OP_CHECKMULTISIG',
OP_CHECKMULTISIGVERIFY : 'OP_CHECKMULTISIGVERIFY',
OP_NOP1 : 'OP_NOP1',
- OP_NOP2 : 'OP_NOP2',
+ OP_CHECKLOCKTIMEVERIFY : 'OP_CHECKLOCKTIMEVERIFY',
OP_NOP3 : 'OP_NOP3',
OP_NOP4 : 'OP_NOP4',
OP_NOP5 : 'OP_NOP5',
@@ -591,7 +591,7 @@ OPCODES_BY_NAME = {
'OP_CHECKMULTISIG' : OP_CHECKMULTISIG,
'OP_CHECKMULTISIGVERIFY' : OP_CHECKMULTISIGVERIFY,
'OP_NOP1' : OP_NOP1,
- 'OP_NOP2' : OP_NOP2,
+ 'OP_CHECKLOCKTIMEVERIFY' : OP_CHECKLOCKTIMEVERIFY,
'OP_NOP3' : OP_NOP3,
'OP_NOP4' : OP_NOP4,
'OP_NOP5' : OP_NOP5,
diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py
index 4948680bad..dd39406036 100644
--- a/qa/rpc-tests/test_framework/util.py
+++ b/qa/rpc-tests/test_framework/util.py
@@ -409,3 +409,49 @@ def assert_raises(exc, fun, *args, **kwds):
def satoshi_round(amount):
return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
+
+def create_confirmed_utxos(fee, node, count):
+ node.generate(int(0.5*count)+101)
+ utxos = node.listunspent()
+ iterations = count - len(utxos)
+ addr1 = node.getnewaddress()
+ addr2 = node.getnewaddress()
+ if iterations <= 0:
+ return utxos
+ for i in xrange(iterations):
+ t = utxos.pop()
+ inputs = []
+ inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
+ outputs = {}
+ send_value = t['amount'] - fee
+ outputs[addr1] = satoshi_round(send_value/2)
+ outputs[addr2] = satoshi_round(send_value/2)
+ raw_tx = node.createrawtransaction(inputs, outputs)
+ signed_tx = node.signrawtransaction(raw_tx)["hex"]
+ txid = node.sendrawtransaction(signed_tx)
+
+ while (node.getmempoolinfo()['size'] > 0):
+ node.generate(1)
+
+ utxos = node.listunspent()
+ assert(len(utxos) >= count)
+ return utxos
+
+def create_lots_of_big_transactions(node, txouts, utxos, fee):
+ addr = node.getnewaddress()
+ txids = []
+ for i in xrange(len(utxos)):
+ t = utxos.pop()
+ inputs = []
+ inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
+ outputs = {}
+ send_value = t['amount'] - fee
+ outputs[addr] = satoshi_round(send_value)
+ rawtx = node.createrawtransaction(inputs, outputs)
+ newtx = rawtx[0:92]
+ newtx = newtx + txouts
+ newtx = newtx + rawtx[94:]
+ signresult = node.signrawtransaction(newtx, None, None, "NONE")
+ txid = node.sendrawtransaction(signresult["hex"], True)
+ txids.append(txid)
+ return txids
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index a46866a2be..abeaaf927c 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -179,7 +179,6 @@ public:
vFixedSeeds.clear();
vSeeds.clear();
- vSeeds.push_back(CDNSSeedData("alexykot.me", "testnet-seed.alexykot.me"));
vSeeds.push_back(CDNSSeedData("bitcoin.petertodd.org", "testnet-seed.bitcoin.petertodd.org"));
vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me"));
vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de"));
diff --git a/src/main.cpp b/src/main.cpp
index 41fc0b8098..a43eef07b5 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -800,32 +800,6 @@ void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age) {
pcoinsTip->Uncache(removed);
}
-CAmount GetMinRelayFee(const CTransaction& tx, const CTxMemPool& pool, unsigned int nBytes, bool fAllowFree)
-{
- uint256 hash = tx.GetHash();
- double dPriorityDelta = 0;
- CAmount nFeeDelta = 0;
- pool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
- if (dPriorityDelta > 0 || nFeeDelta > 0)
- return 0;
-
- CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
-
- if (fAllowFree)
- {
- // There is a free transaction area in blocks created by most miners,
- // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
- // to be considered to fall into this category. We don't want to encourage sending
- // multiple transactions instead of one big transaction to avoid fees.
- if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
- nMinFee = 0;
- }
-
- if (!MoneyRange(nMinFee))
- nMinFee = MAX_MONEY;
- return nMinFee;
-}
-
/** Convert CValidationState to a human-readable message for logging */
std::string FormatStateMessage(const CValidationState &state)
{
@@ -968,6 +942,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
CAmount nValueOut = tx.GetValueOut();
CAmount nFees = nValueIn-nValueOut;
+ // nModifiedFees includes any fee deltas from PrioritiseTransaction
+ CAmount nModifiedFees = nFees;
+ double nPriorityDummy = 0;
+ pool.ApplyDeltas(hash, nPriorityDummy, nModifiedFees);
+
CAmount inChainInputValue;
double dPriority = view.GetPriority(tx, chainActive.Height(), inChainInputValue);
@@ -985,16 +964,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOps);
unsigned int nSize = entry.GetTxSize();
- // Don't accept it if it can't get into a block
- CAmount txMinFee = GetMinRelayFee(tx, pool, nSize, true);
- if (fLimitFree && nFees < txMinFee)
- return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false,
- strprintf("%d < %d", nFees, txMinFee));
-
CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize);
- if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) {
+ if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) {
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee));
- } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) {
+ } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nModifiedFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) {
// Require that free transactions have sufficient priority to be mined in the next block.
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
}
@@ -1002,7 +975,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
// Continuously rate-limit free (really, very-low-fee) transactions
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
// be annoying or make others' transactions take longer to confirm.
- if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
+ if (fLimitFree && nModifiedFees < ::minRelayTxFee.GetFee(nSize))
{
static CCriticalSection csFreeLimiter;
static double dFreeCount;
@@ -1067,7 +1040,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
LOCK(pool.cs);
if (setConflicts.size())
{
- CFeeRate newFeeRate(nFees, nSize);
+ CFeeRate newFeeRate(nModifiedFees, nSize);
set<uint256> setConflictsParents;
const int maxDescendantsToVisit = 100;
CTxMemPool::setEntries setIterConflicting;
@@ -1110,7 +1083,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
// ignored when deciding whether or not to replace, we do
// require the replacement to pay more overall fees too,
// mitigating most cases.
- CFeeRate oldFeeRate(mi->GetFee(), mi->GetTxSize());
+ CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize());
if (newFeeRate <= oldFeeRate)
{
return state.DoS(0,
@@ -1138,7 +1111,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
pool.CalculateDescendants(it, allConflicting);
}
BOOST_FOREACH(CTxMemPool::txiter it, allConflicting) {
- nConflictingFees += it->GetFee();
+ nConflictingFees += it->GetModifiedFee();
nConflictingSize += it->GetTxSize();
}
} else {
@@ -1171,16 +1144,16 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
// The replacement must pay greater fees than the transactions it
// replaces - if we did the bandwidth used by those conflicting
// transactions would not be paid for.
- if (nFees < nConflictingFees)
+ if (nModifiedFees < nConflictingFees)
{
return state.DoS(0, error("AcceptToMemoryPool: rejecting replacement %s, less fees than conflicting txs; %s < %s",
- hash.ToString(), FormatMoney(nFees), FormatMoney(nConflictingFees)),
+ hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)),
REJECT_INSUFFICIENTFEE, "insufficient fee");
}
// Finally in addition to paying more fees than the conflicts the
// new transaction must pay for its own bandwidth.
- CAmount nDeltaFees = nFees - nConflictingFees;
+ CAmount nDeltaFees = nModifiedFees - nConflictingFees;
if (nDeltaFees < ::minRelayTxFee.GetFee(nSize))
{
return state.DoS(0,
@@ -1218,7 +1191,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
LogPrint("mempool", "replacing tx %s with %s for %s BTC additional fees, %d delta bytes\n",
it->GetTx().GetHash().ToString(),
hash.ToString(),
- FormatMoney(nFees - nConflictingFees),
+ FormatMoney(nModifiedFees - nConflictingFees),
(int)nSize - (int)nConflictingSize);
}
pool.RemoveStaged(allConflicting);
diff --git a/src/main.h b/src/main.h
index 25a0063873..7ae4893e07 100644
--- a/src/main.h
+++ b/src/main.h
@@ -300,8 +300,6 @@ struct CDiskTxPos : public CDiskBlockPos
};
-CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree);
-
/**
* Count ECDSA signature operations the old-fashioned (pre-0.6) way
* @return number of sigops this transaction's outputs will produce when spent
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index e709f8515b..00411741f1 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -1153,7 +1153,7 @@
</message>
<message>
<location line="+1"/>
- <source>Reset all settings changes made over the GUI</source>
+ <source>Reset all settings changed in the GUI</source>
<translation type="unfinished"></translation>
</message>
</context>
diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp
index 81b597e2eb..088578b7a9 100644
--- a/src/qt/utilitydialog.cpp
+++ b/src/qt/utilitydialog.cpp
@@ -84,7 +84,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
strUsage += HelpMessageOpt("-min", tr("Start minimized").toStdString());
strUsage += HelpMessageOpt("-rootcertificates=<file>", tr("Set SSL root certificates for payment request (default: -system-)").toStdString());
strUsage += HelpMessageOpt("-splash", strprintf(tr("Show splash screen on startup (default: %u)").toStdString(), DEFAULT_SPLASHSCREEN));
- strUsage += HelpMessageOpt("-resetguisettings", tr("Reset all settings changes made over the GUI").toStdString());
+ strUsage += HelpMessageOpt("-resetguisettings", tr("Reset all settings changed in the GUI").toStdString());
if (showDebug) {
strUsage += HelpMessageOpt("-uiplatform", strprintf("Select platform to customize UI for (one of windows, macosx, other; default: %s)", BitcoinGUI::DEFAULT_UIPLATFORM));
}
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index ee04636ce8..73e6f8029b 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -197,7 +197,7 @@ UniValue mempoolToJSON(bool fVerbose = false)
info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
- info.push_back(Pair("descendantfees", e.GetFeesWithDescendants()));
+ info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants()));
const CTransaction& tx = e.GetTx();
set<string> setDepends;
BOOST_FOREACH(const CTxIn& txin, tx.vin)
@@ -255,7 +255,7 @@ UniValue getrawmempool(const UniValue& params, bool fHelp)
" \"currentpriority\" : n, (numeric) transaction priority now\n"
" \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
" \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n"
- " \"descendantfees\" : n, (numeric) fees of in-mempool descendants (including this one)\n"
+ " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n"
" \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
" \"transactionid\", (string) parent transaction id\n"
" ... ]\n"
diff --git a/src/script/script.cpp b/src/script/script.cpp
index 9c77ed9fc1..a7ba57e65b 100644
--- a/src/script/script.cpp
+++ b/src/script/script.cpp
@@ -131,7 +131,7 @@ const char* GetOpName(opcodetype opcode)
// expanson
case OP_NOP1 : return "OP_NOP1";
- case OP_NOP2 : return "OP_NOP2";
+ case OP_CHECKLOCKTIMEVERIFY : return "OP_CHECKLOCKTIMEVERIFY";
case OP_NOP3 : return "OP_NOP3";
case OP_NOP4 : return "OP_NOP4";
case OP_NOP5 : return "OP_NOP5";
diff --git a/src/script/script.h b/src/script/script.h
index 3650957fc9..7a37b66ccf 100644
--- a/src/script/script.h
+++ b/src/script/script.h
@@ -162,8 +162,8 @@ enum opcodetype
// expansion
OP_NOP1 = 0xb0,
- OP_NOP2 = 0xb1,
- OP_CHECKLOCKTIMEVERIFY = OP_NOP2,
+ OP_CHECKLOCKTIMEVERIFY = 0xb1,
+ OP_NOP2 = OP_CHECKLOCKTIMEVERIFY,
OP_NOP3 = 0xb2,
OP_NOP4 = 0xb3,
OP_NOP5 = 0xb4,
diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json
index 7afa2abf49..7ce7e0879c 100644
--- a/src/test/data/script_invalid.json
+++ b/src/test/data/script_invalid.json
@@ -160,12 +160,12 @@
["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "disabled"],
["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "disabled"],
-["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"],
-["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"],
+["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"],
+["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"],
["Ensure 100% coverage of discouraged NOPS"],
["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
-["1", "NOP2", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json
index a4e15faeaf..e5f0d17b04 100644
--- a/src/test/data/script_valid.json
+++ b/src/test/data/script_valid.json
@@ -232,8 +232,8 @@
["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC"],
-["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"],
-["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"],
+["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"],
+["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"],
["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "Discourage NOPx flag allows OP_NOP"],
@@ -442,7 +442,7 @@
["NOP", "CODESEPARATOR 1", "P2SH,STRICTENC"],
["NOP", "NOP1 1", "P2SH,STRICTENC"],
-["NOP", "NOP2 1", "P2SH,STRICTENC"],
+["NOP", "CHECKLOCKTIMEVERIFY 1", "P2SH,STRICTENC"],
["NOP", "NOP3 1", "P2SH,STRICTENC"],
["NOP", "NOP4 1", "P2SH,STRICTENC"],
["NOP", "NOP5 1", "P2SH,STRICTENC"],
diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json
index cc059e814f..9025841949 100644
--- a/src/test/data/tx_invalid.json
+++ b/src/test/data/tx_invalid.json
@@ -127,66 +127,66 @@
["CHECKLOCKTIMEVERIFY tests"],
["By-height locks, with argument just beyond tx nLockTime"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 CHECKLOCKTIMEVERIFY 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 CHECKLOCKTIMEVERIFY 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKLOCKTIMEVERIFY 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
["Argument missing"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "CHECKLOCKTIMEVERIFY 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000001b1010000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Argument negative with by-blockheight nLockTime=0"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKLOCKTIMEVERIFY 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Argument negative with by-blocktime nLockTime=500,000,000"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKLOCKTIMEVERIFY 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000004005194b1010000000100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Input locked"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1ffffffff0100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Another input being unlocked isn't sufficient; the CHECKLOCKTIMEVERIFY-using input must be unlocked"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"] ,
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"] ,
["0000000000000000000000000000000000000000000000000000000000000200", 1, "1"]],
"010000000200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00020000000000000000000000000000000000000000000000000000000000000100000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Argument/tx height/time mismatch, both versions"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b100000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
["Argument 2^32 with nLockTime=2^32-1"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 CHECKLOCKTIMEVERIFY 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
["Same, but with nLockTime=2^31-1"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKLOCKTIMEVERIFY 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffff7f", "P2SH,CHECKLOCKTIMEVERIFY"],
["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 CHECKLOCKTIMEVERIFY 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Failure due to failing CHECKLOCKTIMEVERIFY in scriptSig"],
diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json
index 0dfef73ae5..76d29bcf26 100644
--- a/src/test/data/tx_valid.json
+++ b/src/test/data/tx_valid.json
@@ -190,35 +190,35 @@
["CHECKLOCKTIMEVERIFY tests"],
["By-height locks, with argument == 0 and == tx nLockTime"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKLOCKTIMEVERIFY 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
["Any non-maxint nSequence is fine"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["The argument can be calculated rather than created directly by a PUSHDATA"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD CHECKLOCKTIMEVERIFY 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
["Perhaps even by an ADD producing a 5-byte result that is out of bounds for other opcodes"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 2147483647 ADD NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 2147483647 ADD CHECKLOCKTIMEVERIFY 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
["5 byte non-minimally-encoded arguments are valid"],
-[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 NOP2 1"]],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 CHECKLOCKTIMEVERIFY 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Valid CHECKLOCKTIMEVERIFY in scriptSig"],
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 0059e4a998..9eff6d0c63 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -985,10 +985,10 @@ BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts)
BOOST_AUTO_TEST_CASE(script_GetScriptAsm)
{
- BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2, true));
- BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true));
- BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2));
- BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY));
+ BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2, true));
+ BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true));
+ BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2));
+ BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY));
string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090");
string pubKey("03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2");
diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
index 8eccc81e30..4ebcb9b667 100644
--- a/src/torcontrol.cpp
+++ b/src/torcontrol.cpp
@@ -618,7 +618,7 @@ void TorController::disconnected_cb(TorControlConnection& conn)
if (!reconnect)
return;
- LogPrint("tor", "tor: Disconnected from Tor control port %s, trying to reconnect\n", target);
+ LogPrint("tor", "tor: Not connected to Tor control port %s, trying to reconnect\n", target);
// Single-shot timer for reconnect. Use exponential backoff.
struct timeval time = MillisToTimeval(int64_t(reconnect_timeout * 1000.0));
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index fea5da8029..c72a1e8c19 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -33,7 +33,7 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
nCountWithDescendants = 1;
nSizeWithDescendants = nTxSize;
- nFeesWithDescendants = nFee;
+ nModFeesWithDescendants = nFee;
CAmount nValueIn = tx.GetValueOut()+nFee;
assert(inChainInputValue <= nValueIn);
@@ -57,6 +57,7 @@ CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const
void CTxMemPoolEntry::UpdateFeeDelta(int64_t newFeeDelta)
{
+ nModFeesWithDescendants += newFeeDelta - feeDelta;
feeDelta = newFeeDelta;
}
@@ -114,7 +115,7 @@ bool CTxMemPool::UpdateForDescendants(txiter updateIt, int maxDescendantsToVisit
BOOST_FOREACH(txiter cit, setAllDescendants) {
if (!setExclude.count(cit->GetTx().GetHash())) {
modifySize += cit->GetTxSize();
- modifyFee += cit->GetFee();
+ modifyFee += cit->GetModifiedFee();
modifyCount++;
cachedDescendants[updateIt].insert(cit);
}
@@ -244,7 +245,7 @@ void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, setEntries &setAncestors
}
const int64_t updateCount = (add ? 1 : -1);
const int64_t updateSize = updateCount * it->GetTxSize();
- const CAmount updateFee = updateCount * it->GetFee();
+ const CAmount updateFee = updateCount * it->GetModifiedFee();
BOOST_FOREACH(txiter ancestorIt, setAncestors) {
mapTx.modify(ancestorIt, update_descendant_state(updateSize, updateFee, updateCount));
}
@@ -304,7 +305,7 @@ void CTxMemPoolEntry::SetDirty()
{
nCountWithDescendants = 0;
nSizeWithDescendants = nTxSize;
- nFeesWithDescendants = nFee;
+ nModFeesWithDescendants = GetModifiedFee();
}
void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount)
@@ -312,8 +313,7 @@ void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t
if (!IsDirty()) {
nSizeWithDescendants += modifySize;
assert(int64_t(nSizeWithDescendants) > 0);
- nFeesWithDescendants += modifyFee;
- assert(nFeesWithDescendants >= 0);
+ nModFeesWithDescendants += modifyFee;
nCountWithDescendants += modifyCount;
assert(int64_t(nCountWithDescendants) > 0);
}
@@ -372,6 +372,17 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
indexed_transaction_set::iterator newit = mapTx.insert(entry).first;
mapLinks.insert(make_pair(newit, TxLinks()));
+ // Update transaction for any feeDelta created by PrioritiseTransaction
+ // TODO: refactor so that the fee delta is calculated before inserting
+ // into mapTx.
+ std::map<uint256, std::pair<double, CAmount> >::const_iterator pos = mapDeltas.find(hash);
+ if (pos != mapDeltas.end()) {
+ const std::pair<double, CAmount> &deltas = pos->second;
+ if (deltas.second) {
+ mapTx.modify(newit, update_fee_delta(deltas.second));
+ }
+ }
+
// Update cachedInnerUsage to include contained transaction's usage.
// (When we update the entry for in-mempool parents, memory usage will be
// further updated.)
@@ -399,15 +410,6 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
}
UpdateAncestorsOf(true, newit, setAncestors);
- // Update transaction's score for any feeDelta created by PrioritiseTransaction
- std::map<uint256, std::pair<double, CAmount> >::const_iterator pos = mapDeltas.find(hash);
- if (pos != mapDeltas.end()) {
- const std::pair<double, CAmount> &deltas = pos->second;
- if (deltas.second) {
- mapTx.modify(newit, update_fee_delta(deltas.second));
- }
- }
-
nTransactionsUpdated++;
totalTxSize += entry.GetTxSize();
minerPolicyEstimator->processTransaction(entry, fCurrentEstimate);
@@ -644,27 +646,24 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
CTxMemPool::setEntries setChildrenCheck;
std::map<COutPoint, CInPoint>::const_iterator iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0));
int64_t childSizes = 0;
- CAmount childFees = 0;
+ CAmount childModFee = 0;
for (; iter != mapNextTx.end() && iter->first.hash == it->GetTx().GetHash(); ++iter) {
txiter childit = mapTx.find(iter->second.ptx->GetHash());
assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions
if (setChildrenCheck.insert(childit).second) {
childSizes += childit->GetTxSize();
- childFees += childit->GetFee();
+ childModFee += childit->GetModifiedFee();
}
}
assert(setChildrenCheck == GetMemPoolChildren(it));
- // Also check to make sure size/fees is greater than sum with immediate children.
+ // Also check to make sure size is greater than sum with immediate children.
// just a sanity check, not definitive that this calc is correct...
- // also check that the size is less than the size of the entire mempool.
if (!it->IsDirty()) {
assert(it->GetSizeWithDescendants() >= childSizes + it->GetTxSize());
- assert(it->GetFeesWithDescendants() >= childFees + it->GetFee());
} else {
assert(it->GetSizeWithDescendants() == it->GetTxSize());
- assert(it->GetFeesWithDescendants() == it->GetFee());
+ assert(it->GetModFeesWithDescendants() == it->GetModifiedFee());
}
- assert(it->GetFeesWithDescendants() >= 0);
if (fDependsWait)
waitingOnDependants.push_back(&(*it));
@@ -788,6 +787,14 @@ void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash,
txiter it = mapTx.find(hash);
if (it != mapTx.end()) {
mapTx.modify(it, update_fee_delta(deltas.second));
+ // Now update all ancestors' modified fees with descendants
+ setEntries setAncestors;
+ uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
+ std::string dummy;
+ CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false);
+ BOOST_FOREACH(txiter ancestorIt, setAncestors) {
+ mapTx.modify(ancestorIt, update_descendant_state(0, nFeeDelta, 0));
+ }
}
}
LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta));
@@ -956,7 +963,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<uint256>* pvNoSpendsRe
// "minimum reasonable fee rate" (ie some value under which we consider txn
// to have 0 fee). This way, we don't allow txn to enter mempool with feerate
// equal to txn which were removed with no block in between.
- CFeeRate removed(it->GetFeesWithDescendants(), it->GetSizeWithDescendants());
+ CFeeRate removed(it->GetModFeesWithDescendants(), it->GetSizeWithDescendants());
removed += minReasonableRelayFee;
trackPackageRemoved(removed);
maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
diff --git a/src/txmempool.h b/src/txmempool.h
index 9203171868..4b726cc902 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -44,12 +44,12 @@ class CTxMemPool;
* ("descendant" transactions).
*
* When a new entry is added to the mempool, we update the descendant state
- * (nCountWithDescendants, nSizeWithDescendants, and nFeesWithDescendants) for
+ * (nCountWithDescendants, nSizeWithDescendants, and nModFeesWithDescendants) for
* all ancestors of the newly added transaction.
*
* If updating the descendant state is skipped, we can mark the entry as
- * "dirty", and set nSizeWithDescendants/nFeesWithDescendants to equal nTxSize/
- * nTxFee. (This can potentially happen during a reorg, where we limit the
+ * "dirty", and set nSizeWithDescendants/nModFeesWithDescendants to equal nTxSize/
+ * nFee+feeDelta. (This can potentially happen during a reorg, where we limit the
* amount of work we're willing to do to avoid consuming too much CPU.)
*
*/
@@ -74,11 +74,11 @@ private:
// Information about descendants of this transaction that are in the
// mempool; if we remove this transaction we must remove all of these
// descendants as well. if nCountWithDescendants is 0, treat this entry as
- // dirty, and nSizeWithDescendants and nFeesWithDescendants will not be
+ // dirty, and nSizeWithDescendants and nModFeesWithDescendants will not be
// correct.
uint64_t nCountWithDescendants; //! number of descendant transactions
uint64_t nSizeWithDescendants; //! ... and size
- CAmount nFeesWithDescendants; //! ... and total fees (all including us)
+ CAmount nModFeesWithDescendants; //! ... and total fees (all including us)
public:
CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
@@ -104,7 +104,8 @@ public:
// Adjusts the descendant state, if this entry is not dirty.
void UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount);
- // Updates the fee delta used for mining priority score
+ // Updates the fee delta used for mining priority score, and the
+ // modified fees with descendants.
void UpdateFeeDelta(int64_t feeDelta);
/** We can set the entry to be dirty if doing the full calculation of in-
@@ -116,7 +117,7 @@ public:
uint64_t GetCountWithDescendants() const { return nCountWithDescendants; }
uint64_t GetSizeWithDescendants() const { return nSizeWithDescendants; }
- CAmount GetFeesWithDescendants() const { return nFeesWithDescendants; }
+ CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; }
bool GetSpendsCoinbase() const { return spendsCoinbase; }
};
@@ -163,27 +164,27 @@ struct mempoolentry_txid
}
};
-/** \class CompareTxMemPoolEntryByFee
+/** \class CompareTxMemPoolEntryByDescendantScore
*
- * Sort an entry by max(feerate of entry's tx, feerate with all descendants).
+ * Sort an entry by max(score/size of entry's tx, score/size with all descendants).
*/
-class CompareTxMemPoolEntryByFee
+class CompareTxMemPoolEntryByDescendantScore
{
public:
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b)
{
- bool fUseADescendants = UseDescendantFeeRate(a);
- bool fUseBDescendants = UseDescendantFeeRate(b);
+ bool fUseADescendants = UseDescendantScore(a);
+ bool fUseBDescendants = UseDescendantScore(b);
- double aFees = fUseADescendants ? a.GetFeesWithDescendants() : a.GetFee();
+ double aModFee = fUseADescendants ? a.GetModFeesWithDescendants() : a.GetModifiedFee();
double aSize = fUseADescendants ? a.GetSizeWithDescendants() : a.GetTxSize();
- double bFees = fUseBDescendants ? b.GetFeesWithDescendants() : b.GetFee();
+ double bModFee = fUseBDescendants ? b.GetModFeesWithDescendants() : b.GetModifiedFee();
double bSize = fUseBDescendants ? b.GetSizeWithDescendants() : b.GetTxSize();
// Avoid division by rewriting (a/b > c/d) as (a*d > c*b).
- double f1 = aFees * bSize;
- double f2 = aSize * bFees;
+ double f1 = aModFee * bSize;
+ double f2 = aSize * bModFee;
if (f1 == f2) {
return a.GetTime() >= b.GetTime();
@@ -191,11 +192,11 @@ public:
return f1 < f2;
}
- // Calculate which feerate to use for an entry (avoiding division).
- bool UseDescendantFeeRate(const CTxMemPoolEntry &a)
+ // Calculate which score to use for an entry (avoiding division).
+ bool UseDescendantScore(const CTxMemPoolEntry &a)
{
- double f1 = (double)a.GetFee() * a.GetSizeWithDescendants();
- double f2 = (double)a.GetFeesWithDescendants() * a.GetTxSize();
+ double f1 = (double)a.GetModifiedFee() * a.GetSizeWithDescendants();
+ double f2 = (double)a.GetModFeesWithDescendants() * a.GetTxSize();
return f2 > f1;
}
};
@@ -350,7 +351,7 @@ public:
// sorted by fee rate
boost::multi_index::ordered_non_unique<
boost::multi_index::identity<CTxMemPoolEntry>,
- CompareTxMemPoolEntryByFee
+ CompareTxMemPoolEntryByDescendantScore
>,
// sorted by entry time
boost::multi_index::ordered_non_unique<