From b1bb30cb3a6ebbfaf2d98241e6a94233581e1c9e Mon Sep 17 00:00:00 2001 From: lateminer Date: Thu, 11 Oct 2018 22:02:52 +0300 Subject: [PATCH] Remove address indexes --- .gitignore | 1 - Makefile.am | 5 - configure.ac | 4 +- qa/pull-tester/rpc-tests.py | 3 - qa/rpc-tests/addressindex.py | 349 --------------------- qa/rpc-tests/spentindex.py | 139 --------- qa/rpc-tests/timestampindex.py | 61 ---- qa/rpc-tests/txindex.py | 73 ----- src/Makefile.am | 18 -- src/Makefile.test.include | 9 +- src/addressindex.h | 82 ----- src/dbwrapper.cpp | 10 +- src/dbwrapper.h | 4 +- src/init.cpp | 25 +- src/main.cpp | 303 ------------------ src/main.h | 351 --------------------- src/rpc/blockchain.cpp | 208 ------------- src/rpc/client.cpp | 9 - src/rpc/misc.cpp | 537 -------------------------------- src/rpc/rawtransaction.cpp | 122 +------- src/script/script.cpp | 15 +- src/script/script.h | 3 - src/serialize.h | 11 - src/spentindex.h | 98 ------ src/test/data/wallet.dat | Bin 16384 -> 0 bytes src/test/dbwrapper_tests.cpp | 43 --- src/test/script_P2PKH_tests.cpp | 59 ---- src/test/wallet-utility.py | 61 ---- src/txdb.cpp | 169 +--------- src/txdb.h | 28 +- src/txmempool.cpp | 141 --------- src/txmempool.h | 23 -- src/wallet-utility.cpp | 340 -------------------- 33 files changed, 24 insertions(+), 3280 deletions(-) delete mode 100755 qa/rpc-tests/addressindex.py delete mode 100755 qa/rpc-tests/spentindex.py delete mode 100755 qa/rpc-tests/timestampindex.py delete mode 100755 qa/rpc-tests/txindex.py delete mode 100644 src/addressindex.h delete mode 100644 src/spentindex.h delete mode 100644 src/test/data/wallet.dat delete mode 100644 src/test/script_P2PKH_tests.cpp delete mode 100755 src/test/wallet-utility.py delete mode 100644 src/wallet-utility.cpp diff --git a/.gitignore b/.gitignore index 29ccd6cf9..a01b000d4 100644 --- a/.gitignore +++ b/.gitignore @@ -114,6 +114,5 @@ share/BitcoindComparisonTool.jar /doc/doxygen/ libbitcoinconsensus.pc -wallet-utility /.cproject /.project diff --git a/Makefile.am b/Makefile.am index c64349c48..5666dffca 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,7 +12,6 @@ endif BITCOIND_BIN=$(top_builddir)/src/$(BITCOIN_DAEMON_NAME)$(EXEEXT) BITCOIN_QT_BIN=$(top_builddir)/src/qt/$(BITCOIN_GUI_NAME)$(EXEEXT) BITCOIN_CLI_BIN=$(top_builddir)/src/$(BITCOIN_CLI_NAME)$(EXEEXT) -WALLET_UTILITY_BIN=$(top_builddir)/src/wallet-utility$(EXEEXT) BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT) OSX_APP=Blackmore-Qt.app @@ -56,7 +55,6 @@ $(BITCOIN_WIN_INSTALLER): all-recursive STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIND_BIN) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_QT_BIN) $(top_builddir)/release STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_CLI_BIN) $(top_builddir)/release - STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(WALLET_UTILITY_BIN) $(top_builddir)/release @test -f $(MAKENSIS) && $(MAKENSIS) -V2 $(top_builddir)/share/setup.nsi || \ echo error: could not build $@ @echo built $@ @@ -139,9 +137,6 @@ $(BITCOIND_BIN): FORCE $(BITCOIN_CLI_BIN): FORCE $(MAKE) -C src $(@F) -$(WALLET_UTILITY_BIN): FORCE - $(MAKE) -C src $(@F) - if USE_LCOV baseline.info: diff --git a/configure.ac b/configure.ac index 3ed63d960..54269654f 100644 --- a/configure.ac +++ b/configure.ac @@ -229,7 +229,7 @@ CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" AC_ARG_WITH([utils], [AS_HELP_STRING([--with-utils], - [build bitcoin-cli bitcoin-tx wallet-utility (default=yes)])], + [build bitcoin-cli bitcoin-tx (default=yes)])], [build_bitcoin_utils=$withval], [build_bitcoin_utils=yes]) @@ -895,7 +895,7 @@ AC_MSG_CHECKING([whether to build bitcoind]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) AC_MSG_RESULT($build_bitcoind) -AC_MSG_CHECKING([whether to build utils (bitcoin-cli bitcoin-tx wallet-utility)]) +AC_MSG_CHECKING([whether to build utils (bitcoin-cli bitcoin-tx)]) AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes]) AC_MSG_RESULT($build_bitcoin_utils) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 7b220b5b1..a56fa40c8 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -100,9 +100,6 @@ testScripts = [ 'walletbackup.py', 'nodehandling.py', 'reindex.py', - 'addressindex.py', - 'timestampindex.py', - 'spentindex.py', 'decodescript.py', 'p2p-fullblocktest.py', 'blockchain.py', diff --git a/qa/rpc-tests/addressindex.py b/qa/rpc-tests/addressindex.py deleted file mode 100755 index 8b0b6d38a..000000000 --- a/qa/rpc-tests/addressindex.py +++ /dev/null @@ -1,349 +0,0 @@ -#!/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 addressindex generation and fetching -# - -import time -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from test_framework.script import * -from test_framework.mininode import * -import binascii - -class AddressIndexTest(BitcoinTestFramework): - - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 4) - - def setup_network(self): - self.nodes = [] - # Nodes 0/1 are "wallet" nodes - self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-relaypriority=0"])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-addressindex"])) - # Nodes 2/3 are used for testing - self.nodes.append(start_node(2, self.options.tmpdir, ["-debug", "-addressindex", "-relaypriority=0"])) - self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-addressindex"])) - connect_nodes(self.nodes[0], 1) - connect_nodes(self.nodes[0], 2) - connect_nodes(self.nodes[0], 3) - - self.is_network_split = False - self.sync_all() - - def run_test(self): - print "Mining blocks..." - self.nodes[0].generate(105) - self.sync_all() - - chain_height = self.nodes[1].getblockcount() - assert_equal(chain_height, 105) - assert_equal(self.nodes[1].getbalance(), 0) - assert_equal(self.nodes[2].getbalance(), 0) - - # Check that balances are correct - balance0 = self.nodes[1].getaddressbalance("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") - assert_equal(balance0["balance"], 0) - - # Check p2pkh and p2sh address indexes - print "Testing p2pkh and p2sh address index..." - - txid0 = self.nodes[0].sendtoaddress("mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", 10) - self.nodes[0].generate(1) - - txidb0 = self.nodes[0].sendtoaddress("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", 10) - self.nodes[0].generate(1) - - txid1 = self.nodes[0].sendtoaddress("mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", 15) - self.nodes[0].generate(1) - - txidb1 = self.nodes[0].sendtoaddress("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", 15) - self.nodes[0].generate(1) - - txid2 = self.nodes[0].sendtoaddress("mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", 20) - self.nodes[0].generate(1) - - txidb2 = self.nodes[0].sendtoaddress("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", 20) - self.nodes[0].generate(1) - - self.sync_all() - - txids = self.nodes[1].getaddresstxids("mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs") - assert_equal(len(txids), 3) - assert_equal(txids[0], txid0) - assert_equal(txids[1], txid1) - assert_equal(txids[2], txid2) - - txidsb = self.nodes[1].getaddresstxids("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") - assert_equal(len(txidsb), 3) - assert_equal(txidsb[0], txidb0) - assert_equal(txidsb[1], txidb1) - assert_equal(txidsb[2], txidb2) - - # Check that limiting by height works - print "Testing querying txids by range of block heights.." - height_txids = self.nodes[1].getaddresstxids({ - "addresses": ["2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br"], - "start": 105, - "end": 110 - }) - assert_equal(len(height_txids), 2) - assert_equal(height_txids[0], txidb0) - assert_equal(height_txids[1], txidb1) - - # Check that multiple addresses works - multitxids = self.nodes[1].getaddresstxids({"addresses": ["2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", "mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs"]}) - assert_equal(len(multitxids), 6) - assert_equal(multitxids[0], txid0) - assert_equal(multitxids[1], txidb0) - assert_equal(multitxids[2], txid1) - assert_equal(multitxids[3], txidb1) - assert_equal(multitxids[4], txid2) - assert_equal(multitxids[5], txidb2) - - # Check that balances are correct - balance0 = self.nodes[1].getaddressbalance("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") - assert_equal(balance0["balance"], 45 * 100000000) - - # Check that outputs with the same address will only return one txid - print "Testing for txid uniqueness..." - addressHash = "6349a418fc4578d10a372b54b45c280cc8c4382f".decode("hex") - scriptPubKey = CScript([OP_HASH160, addressHash, OP_EQUAL]) - unspent = self.nodes[0].listunspent() - tx = CTransaction() - tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))] - tx.vout = [CTxOut(10, scriptPubKey), CTxOut(11, scriptPubKey)] - tx.rehash() - - signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) - sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True) - - self.nodes[0].generate(1) - self.sync_all() - - txidsmany = self.nodes[1].getaddresstxids("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") - assert_equal(len(txidsmany), 4) - assert_equal(txidsmany[3], sent_txid) - - # Check that balances are correct - print "Testing balances..." - balance0 = self.nodes[1].getaddressbalance("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br") - assert_equal(balance0["balance"], 45 * 100000000 + 21) - - # Check that balances are correct after spending - print "Testing balances after spending..." - privkey2 = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG" - address2 = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW" - addressHash2 = "0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc".decode("hex") - scriptPubKey2 = CScript([OP_DUP, OP_HASH160, addressHash2, OP_EQUALVERIFY, OP_CHECKSIG]) - self.nodes[0].importprivkey(privkey2) - - unspent = self.nodes[0].listunspent() - tx = CTransaction() - tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))] - amount = unspent[0]["amount"] * 100000000 - tx.vout = [CTxOut(amount, scriptPubKey2)] - tx.rehash() - signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) - spending_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True) - self.nodes[0].generate(1) - self.sync_all() - balance1 = self.nodes[1].getaddressbalance(address2) - assert_equal(balance1["balance"], amount) - - tx = CTransaction() - tx.vin = [CTxIn(COutPoint(int(spending_txid, 16), 0))] - send_amount = 1 * 100000000 + 12840 - change_amount = amount - send_amount - 10000 - tx.vout = [CTxOut(change_amount, scriptPubKey2), CTxOut(send_amount, scriptPubKey)] - tx.rehash() - - signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) - sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True) - self.nodes[0].generate(1) - self.sync_all() - - balance2 = self.nodes[1].getaddressbalance(address2) - assert_equal(balance2["balance"], change_amount) - - # Check that deltas are returned correctly - deltas = self.nodes[1].getaddressdeltas({"addresses": [address2], "start": 1, "end": 200}) - balance3 = 0 - for delta in deltas: - balance3 += delta["satoshis"] - assert_equal(balance3, change_amount) - assert_equal(deltas[0]["address"], address2) - assert_equal(deltas[0]["blockindex"], 1) - - # Check that entire range will be queried - deltasAll = self.nodes[1].getaddressdeltas({"addresses": [address2]}) - assert_equal(len(deltasAll), len(deltas)) - - # Check that deltas can be returned from range of block heights - deltas = self.nodes[1].getaddressdeltas({"addresses": [address2], "start": 113, "end": 113}) - assert_equal(len(deltas), 1) - - # Check that unspent outputs can be queried - print "Testing utxos..." - utxos = self.nodes[1].getaddressutxos({"addresses": [address2]}) - assert_equal(len(utxos), 1) - assert_equal(utxos[0]["satoshis"], change_amount) - - # Check that indexes will be updated with a reorg - print "Testing reorg..." - - best_hash = self.nodes[0].getbestblockhash() - self.nodes[0].invalidateblock(best_hash) - self.nodes[1].invalidateblock(best_hash) - self.nodes[2].invalidateblock(best_hash) - self.nodes[3].invalidateblock(best_hash) - self.sync_all() - - balance4 = self.nodes[1].getaddressbalance(address2) - assert_equal(balance4, balance1) - - utxos2 = self.nodes[1].getaddressutxos({"addresses": [address2]}) - assert_equal(len(utxos2), 1) - assert_equal(utxos2[0]["satoshis"], amount) - - # Check sorting of utxos - self.nodes[2].generate(150) - - txidsort1 = self.nodes[2].sendtoaddress(address2, 50) - self.nodes[2].generate(1) - txidsort2 = self.nodes[2].sendtoaddress(address2, 50) - self.nodes[2].generate(1) - self.sync_all() - - utxos3 = self.nodes[1].getaddressutxos({"addresses": [address2]}) - assert_equal(len(utxos3), 3) - assert_equal(utxos3[0]["height"], 114) - assert_equal(utxos3[1]["height"], 264) - assert_equal(utxos3[2]["height"], 265) - - # Check mempool indexing - print "Testing mempool indexing..." - - privKey3 = "cVfUn53hAbRrDEuMexyfgDpZPhF7KqXpS8UZevsyTDaugB7HZ3CD" - address3 = "mw4ynwhS7MmrQ27hr82kgqu7zryNDK26JB" - addressHash3 = "aa9872b5bbcdb511d89e0e11aa27da73fd2c3f50".decode("hex") - scriptPubKey3 = CScript([OP_DUP, OP_HASH160, addressHash3, OP_EQUALVERIFY, OP_CHECKSIG]) - address4 = "2N8oFVB2vThAKury4vnLquW2zVjsYjjAkYQ" - scriptPubKey4 = CScript([OP_HASH160, addressHash3, OP_EQUAL]) - unspent = self.nodes[2].listunspent() - - tx = CTransaction() - tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))] - amount = unspent[0]["amount"] * 100000000 - tx.vout = [CTxOut(amount, scriptPubKey3)] - tx.rehash() - signed_tx = self.nodes[2].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) - memtxid1 = self.nodes[2].sendrawtransaction(signed_tx["hex"], True) - time.sleep(2) - - tx2 = CTransaction() - tx2.vin = [CTxIn(COutPoint(int(unspent[1]["txid"], 16), unspent[1]["vout"]))] - amount = unspent[1]["amount"] * 100000000 - tx2.vout = [ - CTxOut(amount / 4, scriptPubKey3), - CTxOut(amount / 4, scriptPubKey3), - CTxOut(amount / 4, scriptPubKey4), - CTxOut(amount / 4, scriptPubKey4) - ] - tx2.rehash() - signed_tx2 = self.nodes[2].signrawtransaction(binascii.hexlify(tx2.serialize()).decode("utf-8")) - memtxid2 = self.nodes[2].sendrawtransaction(signed_tx2["hex"], True) - time.sleep(2) - - mempool = self.nodes[2].getaddressmempool({"addresses": [address3]}) - assert_equal(len(mempool), 3) - assert_equal(mempool[0]["txid"], memtxid1) - assert_equal(mempool[0]["address"], address3) - assert_equal(mempool[0]["index"], 0) - assert_equal(mempool[1]["txid"], memtxid2) - assert_equal(mempool[1]["index"], 0) - assert_equal(mempool[2]["txid"], memtxid2) - assert_equal(mempool[2]["index"], 1) - - self.nodes[2].generate(1); - self.sync_all(); - mempool2 = self.nodes[2].getaddressmempool({"addresses": [address3]}) - assert_equal(len(mempool2), 0) - - tx = CTransaction() - tx.vin = [ - CTxIn(COutPoint(int(memtxid2, 16), 0)), - CTxIn(COutPoint(int(memtxid2, 16), 1)) - ] - tx.vout = [CTxOut(amount / 2 - 10000, scriptPubKey2)] - tx.rehash() - self.nodes[2].importprivkey(privKey3) - signed_tx3 = self.nodes[2].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) - memtxid3 = self.nodes[2].sendrawtransaction(signed_tx3["hex"], True) - time.sleep(2) - - mempool3 = self.nodes[2].getaddressmempool({"addresses": [address3]}) - assert_equal(len(mempool3), 2) - assert_equal(mempool3[0]["prevtxid"], memtxid2) - assert_equal(mempool3[0]["prevout"], 0) - assert_equal(mempool3[1]["prevtxid"], memtxid2) - assert_equal(mempool3[1]["prevout"], 1) - - # sending and receiving to the same address - privkey1 = "cQY2s58LhzUCmEXN8jtAp1Etnijx78YRZ466w4ikX1V4UpTpbsf8" - address1 = "myAUWSHnwsQrhuMWv4Br6QsCnpB41vFwHn" - address1hash = "c192bff751af8efec15135d42bfeedf91a6f3e34".decode("hex") - address1script = CScript([OP_DUP, OP_HASH160, address1hash, OP_EQUALVERIFY, OP_CHECKSIG]) - - self.nodes[0].sendtoaddress(address1, 10) - self.nodes[0].generate(1) - self.sync_all() - - utxos = self.nodes[1].getaddressutxos({"addresses": [address1]}) - assert_equal(len(utxos), 1) - - tx = CTransaction() - tx.vin = [ - CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["outputIndex"])) - ] - amount = utxos[0]["satoshis"] - 1000 - tx.vout = [CTxOut(amount, address1script)] - tx.rehash() - self.nodes[0].importprivkey(privkey1) - signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) - mem_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True) - - self.sync_all() - mempool_deltas = self.nodes[2].getaddressmempool({"addresses": [address1]}) - assert_equal(len(mempool_deltas), 2) - - # Include chaininfo in results - print "Testing results with chain info..." - - deltas_with_info = self.nodes[1].getaddressdeltas({ - "addresses": [address2], - "start": 1, - "end": 200, - "chainInfo": True - }) - start_block_hash = self.nodes[1].getblockhash(1); - end_block_hash = self.nodes[1].getblockhash(200); - assert_equal(deltas_with_info["start"]["height"], 1) - assert_equal(deltas_with_info["start"]["hash"], start_block_hash) - assert_equal(deltas_with_info["end"]["height"], 200) - assert_equal(deltas_with_info["end"]["hash"], end_block_hash) - - utxos_with_info = self.nodes[1].getaddressutxos({"addresses": [address2], "chainInfo": True}) - expected_tip_block_hash = self.nodes[1].getblockhash(267); - assert_equal(utxos_with_info["height"], 267) - assert_equal(utxos_with_info["hash"], expected_tip_block_hash) - - print "Passed\n" - - -if __name__ == '__main__': - AddressIndexTest().main() diff --git a/qa/rpc-tests/spentindex.py b/qa/rpc-tests/spentindex.py deleted file mode 100755 index 1366dbe31..000000000 --- a/qa/rpc-tests/spentindex.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/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 addressindex generation and fetching -# - -import time -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from test_framework.script import * -from test_framework.mininode import * -import binascii - -class SpentIndexTest(BitcoinTestFramework): - - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 4) - - def setup_network(self): - self.nodes = [] - # Nodes 0/1 are "wallet" nodes - self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-spentindex"])) - # Nodes 2/3 are used for testing - self.nodes.append(start_node(2, self.options.tmpdir, ["-debug", "-spentindex"])) - self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-spentindex", "-txindex"])) - connect_nodes(self.nodes[0], 1) - connect_nodes(self.nodes[0], 2) - connect_nodes(self.nodes[0], 3) - - self.is_network_split = False - self.sync_all() - - def run_test(self): - print "Mining blocks..." - self.nodes[0].generate(105) - self.sync_all() - - chain_height = self.nodes[1].getblockcount() - assert_equal(chain_height, 105) - - # Check that - print "Testing spent index..." - - privkey = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG" - address = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW" - addressHash = "0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc".decode("hex") - scriptPubKey = CScript([OP_DUP, OP_HASH160, addressHash, OP_EQUALVERIFY, OP_CHECKSIG]) - unspent = self.nodes[0].listunspent() - tx = CTransaction() - amount = unspent[0]["amount"] * 100000000 - tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))] - tx.vout = [CTxOut(amount, scriptPubKey)] - tx.rehash() - - signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) - txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True) - self.nodes[0].generate(1) - self.sync_all() - - print "Testing getspentinfo method..." - - # Check that the spentinfo works standalone - info = self.nodes[1].getspentinfo({"txid": unspent[0]["txid"], "index": unspent[0]["vout"]}) - assert_equal(info["txid"], txid) - assert_equal(info["index"], 0) - assert_equal(info["height"], 106) - - print "Testing getrawtransaction method..." - - # Check that verbose raw transaction includes spent info - txVerbose = self.nodes[3].getrawtransaction(unspent[0]["txid"], 1) - assert_equal(txVerbose["vout"][unspent[0]["vout"]]["spentTxId"], txid) - assert_equal(txVerbose["vout"][unspent[0]["vout"]]["spentIndex"], 0) - assert_equal(txVerbose["vout"][unspent[0]["vout"]]["spentHeight"], 106) - - # Check that verbose raw transaction includes input values - txVerbose2 = self.nodes[3].getrawtransaction(txid, 1) - assert_equal(txVerbose2["vin"][0]["value"], Decimal(unspent[0]["amount"])) - assert_equal(txVerbose2["vin"][0]["valueSat"], amount) - - # Check that verbose raw transaction includes address values and input values - privkey2 = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG" - address2 = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW" - addressHash2 = "0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc".decode("hex") - scriptPubKey2 = CScript([OP_DUP, OP_HASH160, addressHash2, OP_EQUALVERIFY, OP_CHECKSIG]) - tx2 = CTransaction() - tx2.vin = [CTxIn(COutPoint(int(txid, 16), 0))] - tx2.vout = [CTxOut(amount, scriptPubKey2)] - tx.rehash() - self.nodes[0].importprivkey(privkey) - signed_tx2 = self.nodes[0].signrawtransaction(binascii.hexlify(tx2.serialize()).decode("utf-8")) - txid2 = self.nodes[0].sendrawtransaction(signed_tx2["hex"], True) - - # Check the mempool index - self.sync_all() - txVerbose3 = self.nodes[1].getrawtransaction(txid2, 1) - assert_equal(txVerbose3["vin"][0]["address"], address2) - assert_equal(txVerbose3["vin"][0]["value"], Decimal(unspent[0]["amount"])) - assert_equal(txVerbose3["vin"][0]["valueSat"], amount) - - # Check the database index - block_hash = self.nodes[0].generate(1) - self.sync_all() - - txVerbose4 = self.nodes[3].getrawtransaction(txid2, 1) - assert_equal(txVerbose4["vin"][0]["address"], address2) - assert_equal(txVerbose4["vin"][0]["value"], Decimal(unspent[0]["amount"])) - assert_equal(txVerbose4["vin"][0]["valueSat"], amount) - - - # Check block deltas - print "Testing getblockdeltas..." - - block = self.nodes[3].getblockdeltas(block_hash[0]) - assert_equal(len(block["deltas"]), 2) - assert_equal(block["deltas"][0]["index"], 0) - assert_equal(len(block["deltas"][0]["inputs"]), 0) - assert_equal(len(block["deltas"][0]["outputs"]), 0) - assert_equal(block["deltas"][1]["index"], 1) - assert_equal(block["deltas"][1]["txid"], txid2) - assert_equal(block["deltas"][1]["inputs"][0]["index"], 0) - assert_equal(block["deltas"][1]["inputs"][0]["address"], "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW") - assert_equal(block["deltas"][1]["inputs"][0]["satoshis"], amount * -1) - assert_equal(block["deltas"][1]["inputs"][0]["prevtxid"], txid) - assert_equal(block["deltas"][1]["inputs"][0]["prevout"], 0) - assert_equal(block["deltas"][1]["outputs"][0]["index"], 0) - assert_equal(block["deltas"][1]["outputs"][0]["address"], "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW") - assert_equal(block["deltas"][1]["outputs"][0]["satoshis"], amount) - - print "Passed\n" - - -if __name__ == '__main__': - SpentIndexTest().main() diff --git a/qa/rpc-tests/timestampindex.py b/qa/rpc-tests/timestampindex.py deleted file mode 100755 index 289c81b2a..000000000 --- a/qa/rpc-tests/timestampindex.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/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 timestampindex generation and fetching -# - -import time - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * - - -class TimestampIndexTest(BitcoinTestFramework): - - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 4) - - def setup_network(self): - self.nodes = [] - # Nodes 0/1 are "wallet" nodes - self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-timestampindex"])) - # Nodes 2/3 are used for testing - self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"])) - self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-timestampindex"])) - connect_nodes(self.nodes[0], 1) - connect_nodes(self.nodes[0], 2) - connect_nodes(self.nodes[0], 3) - - self.is_network_split = False - self.sync_all() - - def run_test(self): - print "Mining 25 blocks..." - blockhashes = self.nodes[0].generate(25) - time.sleep(3) - print "Mining 25 blocks..." - blockhashes.extend(self.nodes[0].generate(25)) - time.sleep(3) - print "Mining 25 blocks..." - blockhashes.extend(self.nodes[0].generate(25)) - self.sync_all() - low = self.nodes[1].getblock(blockhashes[0])["time"] - high = low + 76 - - print "Checking timestamp index..." - hashes = self.nodes[1].getblockhashes(high, low) - - assert_equal(len(hashes), len(blockhashes)) - - assert_equal(hashes, blockhashes) - - print "Passed\n" - - -if __name__ == '__main__': - TimestampIndexTest().main() diff --git a/qa/rpc-tests/txindex.py b/qa/rpc-tests/txindex.py deleted file mode 100755 index b139253b7..000000000 --- a/qa/rpc-tests/txindex.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/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 txindex generation and fetching -# - -import time -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from test_framework.script import * -from test_framework.mininode import * -import binascii - -class TxIndexTest(BitcoinTestFramework): - - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 4) - - def setup_network(self): - self.nodes = [] - # Nodes 0/1 are "wallet" nodes - self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-txindex"])) - # Nodes 2/3 are used for testing - self.nodes.append(start_node(2, self.options.tmpdir, ["-debug", "-txindex"])) - self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-txindex"])) - connect_nodes(self.nodes[0], 1) - connect_nodes(self.nodes[0], 2) - connect_nodes(self.nodes[0], 3) - - self.is_network_split = False - self.sync_all() - - def run_test(self): - print "Mining blocks..." - self.nodes[0].generate(105) - self.sync_all() - - chain_height = self.nodes[1].getblockcount() - assert_equal(chain_height, 105) - - print "Testing transaction index..." - - privkey = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG" - address = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW" - addressHash = "0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc".decode("hex") - scriptPubKey = CScript([OP_DUP, OP_HASH160, addressHash, OP_EQUALVERIFY, OP_CHECKSIG]) - unspent = self.nodes[0].listunspent() - tx = CTransaction() - amount = unspent[0]["amount"] * 100000000 - tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))] - tx.vout = [CTxOut(amount, scriptPubKey)] - tx.rehash() - - signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8")) - txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True) - self.nodes[0].generate(1) - self.sync_all() - - # Check verbose raw transaction results - verbose = self.nodes[3].getrawtransaction(unspent[0]["txid"], 1) - assert_equal(verbose["vout"][0]["valueSat"], 5000000000); - assert_equal(verbose["vout"][0]["value"], 50); - - print "Passed\n" - - -if __name__ == '__main__': - TxIndexTest().main() diff --git a/src/Makefile.am b/src/Makefile.am index 9f7cd5627..f5f8d51c5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -66,16 +66,11 @@ endif if BUILD_BITCOIN_UTILS bin_PROGRAMS += blackmore-cli blackmore-tx -if ENABLE_WALLET - bin_PROGRAMS += wallet-utility -endif endif .PHONY: FORCE check-symbols check-security # bitcoin core # BITCOIN_CORE_H = \ - addressindex.h \ - spentindex.h \ addrman.h \ amount.h \ arith_uint256.h \ @@ -407,14 +402,6 @@ blackmore_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) blackmore_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) blackmore_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -# wallet-utility binary # -if ENABLE_WALLET -wallet_utility_SOURCES = wallet-utility.cpp -wallet_utility_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAG) -wallet_utility_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -wallet_utility_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -endif - if TARGET_WINDOWS blackmore_cli_SOURCES += bitcoin-cli-res.rc endif @@ -426,11 +413,6 @@ blackmore_cli_LDADD = \ $(LIBBITCOIN_CRYPTO) blackmore_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) -if ENABLE_WALLET -wallet_utility_LDADD = libbitcoin_wallet.a $(LIBBITCOIN_COMMON) $(LIBBITCOIN_CRYPTO) $(LIBSECP256K1) $(LIBBITCOIN_UTIL) $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) -endif - -# # blackmore-tx binary # blackmore_tx_SOURCES = bitcoin-tx.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 5d42453cb..78f60daa2 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -17,9 +17,7 @@ EXTRA_DIST += \ test/data/txcreate2.hex \ test/data/txcreatedata1.hex \ test/data/txcreatedata2.hex \ - test/data/txcreatesign.hex \ - test/wallet-utility.py \ - test/data/wallet.dat + test/data/txcreatesign.hex JSON_TEST_FILES = \ test/data/script_valid.json \ @@ -73,7 +71,6 @@ BITCOIN_TESTS =\ test/sanity_tests.cpp \ test/scheduler_tests.cpp \ test/script_P2SH_tests.cpp \ - test/script_P2PKH_tests.cpp \ test/scriptnum_tests.cpp \ test/serialize_tests.cpp \ test/sigopcount_tests.cpp \ @@ -137,10 +134,6 @@ bitcoin_test_clean : FORCE check-local: @echo "Running test/bitcoin-util-test.py..." $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(PYTHON) $(srcdir)/test/bitcoin-util-test.py -if ENABLE_WALLET - @echo "Running test/wallet-utility.py..." - $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(PYTHON) $(srcdir)/test/wallet-utility.py -endif $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check if EMBEDDED_UNIVALUE $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check diff --git a/src/addressindex.h b/src/addressindex.h deleted file mode 100644 index 9e734b84d..000000000 --- a/src/addressindex.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_ADDRESSINDEX_H -#define BITCOIN_ADDRESSINDEX_H - -#include "uint256.h" -#include "amount.h" - -struct CMempoolAddressDelta -{ - int64_t time; - CAmount amount; - uint256 prevhash; - unsigned int prevout; - - CMempoolAddressDelta(int64_t t, CAmount a, uint256 hash, unsigned int out) { - time = t; - amount = a; - prevhash = hash; - prevout = out; - } - - CMempoolAddressDelta(int64_t t, CAmount a) { - time = t; - amount = a; - prevhash.SetNull(); - prevout = 0; - } -}; - -struct CMempoolAddressDeltaKey -{ - int type; - uint160 addressBytes; - uint256 txhash; - unsigned int index; - int spending; - - CMempoolAddressDeltaKey(int addressType, uint160 addressHash, uint256 hash, unsigned int i, int s) { - type = addressType; - addressBytes = addressHash; - txhash = hash; - index = i; - spending = s; - } - - CMempoolAddressDeltaKey(int addressType, uint160 addressHash) { - type = addressType; - addressBytes = addressHash; - txhash.SetNull(); - index = 0; - spending = 0; - } -}; - -struct CMempoolAddressDeltaKeyCompare -{ - bool operator()(const CMempoolAddressDeltaKey& a, const CMempoolAddressDeltaKey& b) const { - if (a.type == b.type) { - if (a.addressBytes == b.addressBytes) { - if (a.txhash == b.txhash) { - if (a.index == b.index) { - return a.spending < b.spending; - } else { - return a.index < b.index; - } - } else { - return a.txhash < b.txhash; - } - } else { - return a.addressBytes < b.addressBytes; - } - } else { - return a.type < b.type; - } - } -}; - -#endif // BITCOIN_ADDRESSINDEX_H diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index 74d9c7bbe..09c68fbe5 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -15,14 +15,14 @@ #include #include -static leveldb::Options GetOptions(size_t nCacheSize, bool compression, int maxOpenFiles) +static leveldb::Options GetOptions(size_t nCacheSize) { leveldb::Options options; options.block_cache = leveldb::NewLRUCache(nCacheSize / 2); options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously options.filter_policy = leveldb::NewBloomFilterPolicy(10); - options.compression = compression ? leveldb::kSnappyCompression : leveldb::kNoCompression; - options.max_open_files = maxOpenFiles; + options.compression = leveldb::kNoCompression; + options.max_open_files = 64; if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) { // LevelDB versions before 1.16 consider short writes to be corruption. Only trigger error // on corruption in later versions. @@ -31,14 +31,14 @@ static leveldb::Options GetOptions(size_t nCacheSize, bool compression, int maxO return options; } -CDBWrapper::CDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory, bool fWipe, bool obfuscate, bool compression, int maxOpenFiles) +CDBWrapper::CDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory, bool fWipe, bool obfuscate) { penv = NULL; readoptions.verify_checksums = true; iteroptions.verify_checksums = true; iteroptions.fill_cache = false; syncoptions.sync = true; - options = GetOptions(nCacheSize, compression, maxOpenFiles); + options = GetOptions(nCacheSize); options.create_if_missing = true; if (fMemory) { penv = leveldb::NewMemEnv(leveldb::Env::Default()); diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 20b5f849e..b974363d3 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -192,10 +192,8 @@ public: * @param[in] fWipe If true, remove all existing data. * @param[in] obfuscate If true, store data obfuscated via simple XOR. If false, XOR * with a zero'd byte array. - * @param[in] compression Enable snappy compression for the database - * @param[in] maxOpenFiles The maximum number of open files for the database */ - CDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false, bool obfuscate = false, bool compression = false, int maxOpenFiles = 64); + CDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false, bool obfuscate = false); ~CDBWrapper(); template diff --git a/src/init.cpp b/src/init.cpp index 2267e8d5c..163b9a73e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -331,10 +331,6 @@ std::string HelpMessage(HelpMessageMode mode) #endif strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), DEFAULT_TXINDEX)); - strUsage += HelpMessageOpt("-addressindex", strprintf(_("Maintain a full address index, used to query for the balance, txids and unspent outputs for addresses (default: %u)"), DEFAULT_ADDRESSINDEX)); - strUsage += HelpMessageOpt("-timestampindex", strprintf(_("Maintain a timestamp index for block hashes, used to query blocks hashes by a range of timestamps (default: %u)"), DEFAULT_TIMESTAMPINDEX)); - strUsage += HelpMessageOpt("-spentindex", strprintf(_("Maintain a full spent index, used to query the spending txid and input index for an outpoint (default: %u)"), DEFAULT_SPENTINDEX)); - strUsage += HelpMessageGroup(_("Connection options:")); strUsage += HelpMessageOpt("-addnode=", _("Add a node to connect to and attempt to keep the connection open")); strUsage += HelpMessageOpt("-banscore=", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), DEFAULT_BANSCORE_THRESHOLD)); @@ -1221,33 +1217,18 @@ bool AppInit2(Config& config, boost::thread_group& threadGroup, CScheduler& sche } } - // block tree db settings - int dbMaxOpenFiles = GetArg("-dbmaxopenfiles", DEFAULT_DB_MAX_OPEN_FILES); - bool dbCompression = GetBoolArg("-dbcompression", DEFAULT_DB_COMPRESSION); - - LogPrintf("Block index database configuration:\n"); - LogPrintf("* Using %d max open files\n", dbMaxOpenFiles); - LogPrintf("* Compression is %s\n", dbCompression ? "enabled" : "disabled"); - // cache size calculations int64_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20); nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greated than nMaxDbcache int64_t nBlockTreeDBCache = nTotalCache / 8; - if (GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX) || GetBoolArg("-spentindex", DEFAULT_SPENTINDEX)) { - // enable 3/4 of the cache if addressindex and/or spentindex is enabled - nBlockTreeDBCache = nTotalCache * 3 / 4; - } else { - if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", DEFAULT_TXINDEX)) { - nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB - } - } + if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", DEFAULT_TXINDEX)) + nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB nTotalCache -= nBlockTreeDBCache; int64_t nCoinDBCache = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache nTotalCache -= nCoinDBCache; nCoinCacheUsage = nTotalCache; // the rest goes to in-memory cache LogPrintf("Cache configuration:\n"); - LogPrintf("* Max cache setting possible %.1fMiB\n", nMaxDbCache); LogPrintf("* Using %.1fMiB for block index database\n", nBlockTreeDBCache * (1.0 / 1024 / 1024)); LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024)); LogPrintf("* Using %.1fMiB for in-memory UTXO set\n", nCoinCacheUsage * (1.0 / 1024 / 1024)); @@ -1268,7 +1249,7 @@ bool AppInit2(Config& config, boost::thread_group& threadGroup, CScheduler& sche delete pcoinscatcher; delete pblocktree; - pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex, dbCompression, dbMaxOpenFiles); + pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex); pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex || fReindexChainState); pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview); pcoinsTip = new CCoinsViewCache(pcoinscatcher); diff --git a/src/main.cpp b/src/main.cpp index 190366ebe..d37596fed 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -75,9 +75,6 @@ int nScriptCheckThreads = 0; bool fImporting = false; bool fReindex = false; bool fTxIndex = false; -bool fAddressIndex = false; -bool fTimestampIndex = false; -bool fSpentIndex = false; bool fHavePruned = false; bool fPruneMode = false; bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG; @@ -1488,16 +1485,6 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C pool.addUnchecked(hash, entry, !IsInitialBlockDownload()); } - // Add memory address index - if (fAddressIndex) { - pool.addAddressIndex(entry, view); - } - - // Add memory spent index - if (fSpentIndex) { - pool.addSpentIndex(entry, view); - } - // trim mempool and check if tx was trimmed if (!fOverrideMempoolLimit) { LimitMempoolSize(pool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); @@ -1523,55 +1510,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return res; } -bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector > &hashes) -{ - if (!fTimestampIndex) - return error("Timestamp index not enabled"); - - if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes)) - return error("Unable to get hashes for timestamps"); - - return true; -} - -bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) -{ - if (!fSpentIndex) - return false; - - if (mempool.getSpentIndex(key, value)) - return true; - - if (!pblocktree->ReadSpentIndex(key, value)) - return false; - - return true; -} - -bool GetAddressIndex(uint160 addressHash, int type, - std::vector > &addressIndex, int start, int end) -{ - if (!fAddressIndex) - return error("address index not enabled"); - - if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end)) - return error("unable to get txids for address"); - - return true; -} - -bool GetAddressUnspent(uint160 addressHash, int type, - std::vector > &unspentOutputs) -{ - if (!fAddressIndex) - return error("address index not enabled"); - - if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs)) - return error("unable to get txids for address"); - - return true; -} - /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow) { @@ -2317,55 +2255,11 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) return error("DisconnectBlock(): block and undo data inconsistent"); - std::vector > addressIndex; - std::vector > addressUnspentIndex; - std::vector > spentIndex; - // undo transactions in reverse order for (int i = block.vtx.size() - 1; i >= 0; i--) { const CTransaction &tx = block.vtx[i]; uint256 hash = tx.GetHash(); - if (fAddressIndex) { - - for (unsigned int k = tx.vout.size(); k-- > 0;) { - const CTxOut &out = tx.vout[k]; - - if (out.scriptPubKey.IsPayToScriptHash()) { - vector hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22); - - // undo receiving activity - addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue)); - - // undo unspent index - addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), hash, k), CAddressUnspentValue())); - - } else if (out.scriptPubKey.IsPayToPublicKeyHash()) { - vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); - - // undo receiving activity - addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue)); - - // undo unspent index - addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue())); - - } else if(out.scriptPubKey.IsPayToPublicKey()){ - uint160 uhashBytes = Hash160(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34); - - // record receiving activity - addressIndex.push_back(make_pair(CAddressIndexKey(1, uhashBytes, pindex->nHeight, i, hash, k, false), out.nValue)); - - // record unspent output - addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uhashBytes, hash, k), CAddressUnspentValue())); - - } else { - continue; - } - - } - - } - // Check that all outputs are available and match the outputs in the block itself // exactly. { @@ -2395,49 +2289,6 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI const CTxInUndo &undo = txundo.vprevout[j]; if (!ApplyTxInUndo(undo, view, out)) fClean = false; - - const CTxIn input = tx.vin[j]; - - if (fSpentIndex) { - // undo and delete the spent index - spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue())); - } - - if (fAddressIndex) { - const CTxOut &prevout = view.GetOutputFor(tx.vin[j]); - if (prevout.scriptPubKey.IsPayToScriptHash()) { - vector hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22); - - // undo spending activity - addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1)); - - // restore unspent index - addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight, tx.nTime))); - - - } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { - vector hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23); - - // undo spending activity - addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1)); - - // restore unspent index - addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight, tx.nTime))); - - } else if(prevout.scriptPubKey.IsPayToPublicKey()){ - uint160 uhashBytes = Hash160(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34); - - // record receiving activity - addressIndex.push_back(make_pair(CAddressIndexKey(1, uhashBytes, pindex->nHeight, i, hash, j, true), prevout.nValue * -1)); - - // record unspent output - addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uhashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight, tx.nTime))); - - } else { - continue; - } - } - } } } @@ -2450,15 +2301,6 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI return true; } - if (fAddressIndex) { - if (!pblocktree->EraseAddressIndex(addressIndex)) { - return AbortNode(state, "Failed to delete address index"); - } - if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) { - return AbortNode(state, "Failed to write address unspent index"); - } - } - return fClean; } @@ -2682,14 +2524,10 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin std::vector > vPos; vPos.reserve(block.vtx.size()); blockundo.vtxundo.reserve(block.vtx.size() - 1); - std::vector > addressIndex; - std::vector > addressUnspentIndex; - std::vector > spentIndex; for (unsigned int i = 0; i < block.vtx.size(); i++) { const CTransaction &tx = block.vtx[i]; - const uint256 txhash = tx.GetHash(); nInputs += tx.vin.size(); nSigOps += GetLegacySigOpCount(tx); @@ -2703,48 +2541,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return state.DoS(100, error("ConnectBlock(): inputs missing/spent"), REJECT_INVALID, "bad-txns-inputs-missingorspent"); - if (fAddressIndex || fSpentIndex) - { - for (size_t j = 0; j < tx.vin.size(); j++) { - - const CTxIn input = tx.vin[j]; - const CTxOut &prevout = view.GetOutputFor(tx.vin[j]); - uint160 hashBytes; - int addressType; - - if (prevout.scriptPubKey.IsPayToScriptHash()) { - hashBytes = uint160(vector (prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22)); - addressType = 2; - } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { - hashBytes = uint160(vector (prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23)); - addressType = 1; - } else if (prevout.scriptPubKey.IsPayToPublicKey()) { - hashBytes = Hash160(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34); - addressType = 1; - } - else { - hashBytes.SetNull(); - addressType = 0; - } - - if (fAddressIndex && addressType > 0) { - - // record spending activity - addressIndex.push_back(make_pair(CAddressIndexKey(addressType, hashBytes, pindex->nHeight, i, txhash, j, true), prevout.nValue * -1)); - - // remove address from unspent index - addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue())); - } - - if (fSpentIndex) { - // add the spent index to determine the txid and input that spent an output - // and to find the amount and address from an input - spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->nHeight, prevout.nValue, addressType, hashBytes))); - } - } - - } - if (fStrictPayToScriptHash) { // Add in sigops done by pay-to-script-hash inputs; @@ -2769,46 +2565,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin control.Add(vChecks); } - if (fAddressIndex) { - for (unsigned int k = 0; k < tx.vout.size(); k++) { - const CTxOut &out = tx.vout[k]; - - if (out.scriptPubKey.IsPayToScriptHash()) { - vector hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22); - - // record receiving activity - addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue)); - - // record unspent output - addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight, tx.nTime))); - - } else if (out.scriptPubKey.IsPayToPublicKeyHash()) { - vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); - - // record receiving activity - addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue)); - - // record unspent output - addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight, tx.nTime))); - - } else if(out.scriptPubKey.IsPayToPublicKey()){ - uint160 uhashBytes = Hash160(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34); - - // record receiving activity - addressIndex.push_back(make_pair(CAddressIndexKey(1, uhashBytes, pindex->nHeight, i, txhash, k, false), out.nValue)); - - // record unspent output - addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uhashBytes, txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight, tx.nTime))); - - } else { - - continue; - - } - - } - } - CTxUndo undoDummy; if (i > 0) { blockundo.vtxundo.push_back(CTxUndo()); @@ -2870,41 +2626,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (!pblocktree->WriteTxIndex(vPos)) return AbortNode(state, "Failed to write transaction index"); - if (fAddressIndex) { - if (!pblocktree->WriteAddressIndex(addressIndex)) { - return AbortNode(state, "Failed to write address index"); - } - - if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) { - return AbortNode(state, "Failed to write address unspent index"); - } - } - - if (fSpentIndex) - if (!pblocktree->UpdateSpentIndex(spentIndex)) - return AbortNode(state, "Failed to write transaction index"); - - if (fTimestampIndex) { - unsigned int logicalTS = pindex->nTime; - unsigned int prevLogicalTS = 0; - - // retrieve logical timestamp of the previous block - if (pindex->pprev) - if (!pblocktree->ReadTimestampBlockIndex(pindex->pprev->GetBlockHash(), prevLogicalTS)) - LogPrintf("%s: Failed to read previous block's logical timestamp\n", __func__); - - if (logicalTS <= prevLogicalTS) { - logicalTS = prevLogicalTS + 1; - LogPrintf("%s: Previous logical timestamp is newer Actual[%d] prevLogical[%d] Logical[%d]\n", __func__, pindex->nTime, prevLogicalTS, logicalTS); - } - - if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(logicalTS, pindex->GetBlockHash()))) - return AbortNode(state, "Failed to write timestamp index"); - - if (!pblocktree->WriteTimestampBlockIndex(CTimestampBlockIndexKey(pindex->GetBlockHash()), CTimestampBlockIndexValue(logicalTS))) - return AbortNode(state, "Failed to write blockhash index"); - } - // add this block to the view's block chain view.SetBestBlock(pindex->GetBlockHash()); @@ -4481,18 +4202,6 @@ bool static LoadBlockIndexDB() pblocktree->ReadFlag("txindex", fTxIndex); LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled"); - // Check whether we have an address index - pblocktree->ReadFlag("addressindex", fAddressIndex); - LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled"); - - // Check whether we have a timestamp index - pblocktree->ReadFlag("timestampindex", fTimestampIndex); - LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled"); - - // Check whether we have a spent index - pblocktree->ReadFlag("spentindex", fSpentIndex); - LogPrintf("%s: spent index %s\n", __func__, fSpentIndex ? "enabled" : "disabled"); - // Load pointer to end of best chain BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); if (it == mapBlockIndex.end()) @@ -4658,18 +4367,6 @@ bool InitBlockIndex(const CChainParams& chainparams) // Use the provided setting for -txindex in the new database fTxIndex = GetBoolArg("-txindex", DEFAULT_TXINDEX); pblocktree->WriteFlag("txindex", fTxIndex); - - // Use the provided setting for -addressindex in the new database - fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX); - pblocktree->WriteFlag("addressindex", fAddressIndex); - - // Use the provided setting for -timestampindex in the new database - fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX); - pblocktree->WriteFlag("timestampindex", fTimestampIndex); - - fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX); - pblocktree->WriteFlag("spentindex", fSpentIndex); - LogPrintf("Initializing databases...\n"); // Only add the genesis block if not reindexing (in which case we reuse the one already on disk) diff --git a/src/main.h b/src/main.h index 57c34f701..deddb3903 100644 --- a/src/main.h +++ b/src/main.h @@ -17,7 +17,6 @@ #include "script/script_error.h" #include "sync.h" #include "versionbits.h" -#include "spentindex.h" #include #include @@ -118,11 +117,6 @@ static const bool DEFAULT_PERMIT_BAREMULTISIG = true; static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20; static const bool DEFAULT_CHECKPOINTS_ENABLED = true; static const bool DEFAULT_TXINDEX = true; -static const bool DEFAULT_ADDRESSINDEX = false; -static const bool DEFAULT_TIMESTAMPINDEX = false; -static const bool DEFAULT_SPENTINDEX = false; -static const unsigned int DEFAULT_DB_MAX_OPEN_FILES = 1000; -static const bool DEFAULT_DB_COMPRESSION = true; static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100; static const bool DEFAULT_TESTSAFEMODE = false; @@ -308,343 +302,6 @@ struct CNodeStateStats { std::vector vHeightInFlight; }; -struct CTimestampIndexIteratorKey { - unsigned int timestamp; - - size_t GetSerializeSize(int nType, int nVersion) const { - return 4; - } - template - void Serialize(Stream& s, int nType, int nVersion) const { - ser_writedata32be(s, timestamp); - } - template - void Unserialize(Stream& s, int nType, int nVersion) { - timestamp = ser_readdata32be(s); - } - - CTimestampIndexIteratorKey(unsigned int time) { - timestamp = time; - } - - CTimestampIndexIteratorKey() { - SetNull(); - } - - void SetNull() { - timestamp = 0; - } -}; - -struct CTimestampIndexKey { - unsigned int timestamp; - uint256 blockHash; - - size_t GetSerializeSize(int nType, int nVersion) const { - return 36; - } - template - void Serialize(Stream& s, int nType, int nVersion) const { - ser_writedata32be(s, timestamp); - blockHash.Serialize(s, nType, nVersion); - } - template - void Unserialize(Stream& s, int nType, int nVersion) { - timestamp = ser_readdata32be(s); - blockHash.Unserialize(s, nType, nVersion); - } - - CTimestampIndexKey(unsigned int time, uint256 hash) { - timestamp = time; - blockHash = hash; - } - - CTimestampIndexKey() { - SetNull(); - } - - void SetNull() { - timestamp = 0; - blockHash.SetNull(); - } -}; - -struct CTimestampBlockIndexKey { - uint256 blockHash; - - size_t GetSerializeSize(int nType, int nVersion) const { - return 32; - } - - template - void Serialize(Stream& s, int nType, int nVersion) const { - blockHash.Serialize(s, nType, nVersion); - } - - template - void Unserialize(Stream& s, int nType, int nVersion) { - blockHash.Unserialize(s, nType, nVersion); - } - - CTimestampBlockIndexKey(uint256 hash) { - blockHash = hash; - } - - CTimestampBlockIndexKey() { - SetNull(); - } - - void SetNull() { - blockHash.SetNull(); - } -}; - -struct CTimestampBlockIndexValue { - unsigned int ltimestamp; - size_t GetSerializeSize(int nType, int nVersion) const { - return 4; - } - - template - void Serialize(Stream& s, int nType, int nVersion) const { - ser_writedata32be(s, ltimestamp); - } - - template - void Unserialize(Stream& s, int nType, int nVersion) { - ltimestamp = ser_readdata32be(s); - } - - CTimestampBlockIndexValue (unsigned int time) { - ltimestamp = time; - } - - CTimestampBlockIndexValue() { - SetNull(); - } - - void SetNull() { - ltimestamp = 0; - } -}; - -struct CAddressUnspentKey { - unsigned int type; - uint160 hashBytes; - uint256 txhash; - size_t index; - - - size_t GetSerializeSize(int nType, int nVersion) const { - return 57; - } - template - void Serialize(Stream& s, int nType, int nVersion) const { - ser_writedata8(s, type); - hashBytes.Serialize(s, nType, nVersion); - txhash.Serialize(s, nType, nVersion); - ser_writedata32(s, index); - } - template - void Unserialize(Stream& s, int nType, int nVersion) { - type = ser_readdata8(s); - hashBytes.Unserialize(s, nType, nVersion); - txhash.Unserialize(s, nType, nVersion); - index = ser_readdata32(s); - } - - CAddressUnspentKey(unsigned int addressType, uint160 addressHash, uint256 txid, size_t indexValue) { - type = addressType; - hashBytes = addressHash; - txhash = txid; - index = indexValue; - } - - CAddressUnspentKey() { - SetNull(); - } - - void SetNull() { - type = 0; - hashBytes.SetNull(); - txhash.SetNull(); - index = 0; - } -}; - -struct CAddressUnspentValue { - CAmount satoshis; - CScript script; - int blockHeight; - uint64_t nTime; - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(satoshis); - READWRITE(*(CScriptBase*)(&script)); - READWRITE(blockHeight); - READWRITE(nTime); - } - - CAddressUnspentValue(CAmount sats, CScript scriptPubKey, int height, uint64_t nTimeVal) { - satoshis = sats; - script = scriptPubKey; - blockHeight = height; - nTime = nTimeVal; - } - - CAddressUnspentValue() { - SetNull(); - } - - void SetNull() { - satoshis = -1; - script.clear(); - blockHeight = 0; - nTime = 0; - } - - bool IsNull() const { - return (satoshis == -1); - } -}; - -struct CAddressIndexKey { - unsigned int type; - uint160 hashBytes; - int blockHeight; - unsigned int txindex; - uint256 txhash; - size_t index; - bool spending; - - size_t GetSerializeSize(int nType, int nVersion) const { - return 66; - } - template - void Serialize(Stream& s, int nType, int nVersion) const { - ser_writedata8(s, type); - hashBytes.Serialize(s, nType, nVersion); - // Heights are stored big-endian for key sorting in LevelDB - ser_writedata32be(s, blockHeight); - ser_writedata32be(s, txindex); - txhash.Serialize(s, nType, nVersion); - ser_writedata32(s, index); - char f = spending; - ser_writedata8(s, f); - } - template - void Unserialize(Stream& s, int nType, int nVersion) { - type = ser_readdata8(s); - hashBytes.Unserialize(s, nType, nVersion); - blockHeight = ser_readdata32be(s); - txindex = ser_readdata32be(s); - txhash.Unserialize(s, nType, nVersion); - index = ser_readdata32(s); - char f = ser_readdata8(s); - spending = f; - } - - CAddressIndexKey(unsigned int addressType, uint160 addressHash, int height, int blockindex, - uint256 txid, size_t indexValue, bool isSpending) { - type = addressType; - hashBytes = addressHash; - blockHeight = height; - txindex = blockindex; - txhash = txid; - index = indexValue; - spending = isSpending; - } - - CAddressIndexKey() { - SetNull(); - } - - void SetNull() { - type = 0; - hashBytes.SetNull(); - blockHeight = 0; - txindex = 0; - txhash.SetNull(); - index = 0; - spending = false; - } - -}; - -struct CAddressIndexIteratorKey { - unsigned int type; - uint160 hashBytes; - - size_t GetSerializeSize(int nType, int nVersion) const { - return 21; - } - template - void Serialize(Stream& s, int nType, int nVersion) const { - ser_writedata8(s, type); - hashBytes.Serialize(s, nType, nVersion); - } - template - void Unserialize(Stream& s, int nType, int nVersion) { - type = ser_readdata8(s); - hashBytes.Unserialize(s, nType, nVersion); - } - - CAddressIndexIteratorKey(unsigned int addressType, uint160 addressHash) { - type = addressType; - hashBytes = addressHash; - } - - CAddressIndexIteratorKey() { - SetNull(); - } - - void SetNull() { - type = 0; - hashBytes.SetNull(); - } -}; - -struct CAddressIndexIteratorHeightKey { - unsigned int type; - uint160 hashBytes; - int blockHeight; - - size_t GetSerializeSize(int nType, int nVersion) const { - return 25; - } - template - void Serialize(Stream& s, int nType, int nVersion) const { - ser_writedata8(s, type); - hashBytes.Serialize(s, nType, nVersion); - ser_writedata32be(s, blockHeight); - } - template - void Unserialize(Stream& s, int nType, int nVersion) { - type = ser_readdata8(s); - hashBytes.Unserialize(s, nType, nVersion); - blockHeight = ser_readdata32be(s); - } - - CAddressIndexIteratorHeightKey(unsigned int addressType, uint160 addressHash, int height) { - type = addressType; - hashBytes = addressHash; - blockHeight = height; - } - - CAddressIndexIteratorHeightKey() { - SetNull(); - } - - void SetNull() { - type = 0; - hashBytes.SetNull(); - blockHeight = 0; - } -}; - struct CDiskTxPos : public CDiskBlockPos { unsigned int nTxOffset; // after header @@ -777,14 +434,6 @@ public: ScriptError GetScriptError() const { return error; } }; -bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector > &hashes); -bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value); -bool GetAddressIndex(uint160 addressHash, int type, - std::vector > &addressIndex, - int start = 0, int end = 0); -bool GetAddressUnspent(uint160 addressHash, int type, - std::vector > &unspentOutputs); - /** Functions for disk access for blocks */ bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index b1be57724..85b04e8f5 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -14,10 +14,6 @@ #include "policy/policy.h" #include "primitives/transaction.h" #include "rpc/server.h" -#include "script/script.h" -#include "script/script_error.h" -#include "script/sign.h" -#include "script/standard.h" #include "streams.h" #include "sync.h" #include "txmempool.h" @@ -98,112 +94,6 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) return result; } -UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex) -{ - UniValue result(UniValue::VOBJ); - result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); - int confirmations = -1; - // Only report confirmations if the block is on the main chain - if (chainActive.Contains(blockindex)) { - confirmations = chainActive.Height() - blockindex->nHeight + 1; - } else { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block is an orphan"); - } - result.push_back(Pair("confirmations", confirmations)); - result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); - result.push_back(Pair("height", blockindex->nHeight)); - result.push_back(Pair("version", block.nVersion)); - result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); - - UniValue deltas(UniValue::VARR); - - for (unsigned int i = 0; i < block.vtx.size(); i++) { - const CTransaction &tx = block.vtx[i]; - const uint256 txhash = tx.GetHash(); - - UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("txid", txhash.GetHex())); - entry.push_back(Pair("index", (int)i)); - - UniValue inputs(UniValue::VARR); - - if (!tx.IsCoinBase()) { - - for (size_t j = 0; j < tx.vin.size(); j++) { - const CTxIn input = tx.vin[j]; - - UniValue delta(UniValue::VOBJ); - - CSpentIndexValue spentInfo; - CSpentIndexKey spentKey(input.prevout.hash, input.prevout.n); - - if (GetSpentIndex(spentKey, spentInfo)) { - if (spentInfo.addressType == 1) { - delta.push_back(Pair("address", EncodeDestination(CKeyID(spentInfo.addressHash)))); - } else if (spentInfo.addressType == 2) { - delta.push_back(Pair("address", EncodeDestination(CScriptID(spentInfo.addressHash)))); - } else { - continue; - } - delta.push_back(Pair("satoshis", -1 * spentInfo.satoshis)); - delta.push_back(Pair("index", (int)j)); - delta.push_back(Pair("prevtxid", input.prevout.hash.GetHex())); - delta.push_back(Pair("prevout", (int)input.prevout.n)); - - inputs.push_back(delta); - } else { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Spent information not available"); - } - - } - } - - entry.push_back(Pair("inputs", inputs)); - - UniValue outputs(UniValue::VARR); - - for (unsigned int k = 0; k < tx.vout.size(); k++) { - const CTxOut &out = tx.vout[k]; - - UniValue delta(UniValue::VOBJ); - - if (out.scriptPubKey.IsPayToScriptHash()) { - vector hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22); - delta.push_back(Pair("address", EncodeDestination(CScriptID(uint160(hashBytes))))); - - } else if (out.scriptPubKey.IsPayToPublicKeyHash()) { - vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); - delta.push_back(Pair("address", EncodeDestination(CKeyID(uint160(hashBytes))))); - } else { - continue; - } - - delta.push_back(Pair("satoshis", out.nValue)); - delta.push_back(Pair("index", (int)k)); - - outputs.push_back(delta); - } - - entry.push_back(Pair("outputs", outputs)); - deltas.push_back(entry); - - } - result.push_back(Pair("deltas", deltas)); - result.push_back(Pair("time", block.GetBlockTime())); - result.push_back(Pair("mediantime", (int64_t)blockindex->GetPastTimeLimit())); - result.push_back(Pair("nonce", (uint64_t)block.nNonce)); - result.push_back(Pair("bits", strprintf("%08x", block.nBits))); - result.push_back(Pair("difficulty", GetDifficulty(blockindex))); - result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); - - if (blockindex->pprev) - result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); - CBlockIndex *pnext = chainActive.Next(blockindex); - if (pnext) - result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); - return result; -} - double GetPoSKernelPS() { int nPoSInterval = 72; @@ -450,102 +340,6 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) return mempoolToJSON(fVerbose); } -UniValue getblockdeltas(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 1) - throw runtime_error(""); - - std::string strHash = params[0].get_str(); - uint256 hash(uint256S(strHash)); - - if (mapBlockIndex.count(hash) == 0) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); - - CBlock block; - CBlockIndex* pblockindex = mapBlockIndex[hash]; - - if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); - - if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); - - return blockToDeltasJSON(block, pblockindex); -} - -UniValue getblockhashes(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() < 2) - throw runtime_error( - "getblockhashes timestamp\n" - "\nReturns array of hashes of blocks within the timestamp range provided.\n" - "\nArguments:\n" - "1. high (numeric, required) The newer block timestamp\n" - "2. low (numeric, required) The older block timestamp\n" - "3. options (string, required) A json object\n" - " {\n" - " \"noOrphans\":true (boolean) will only include blocks on the main chain\n" - " \"logicalTimes\":true (boolean) will include logical timestamps with hashes\n" - " }\n" - "\nResult:\n" - "[\n" - " \"hash\" (string) The block hash\n" - "]\n" - "[\n" - " {\n" - " \"blockhash\": (string) The block hash\n" - " \"logicalts\": (numeric) The logical timestamp\n" - " }\n" - "]\n" - "\nExamples:\n" - + HelpExampleCli("getblockhashes", "1231614698 1231024505") - + HelpExampleRpc("getblockhashes", "1231614698, 1231024505") - + HelpExampleCli("getblockhashes", "1231614698 1231024505 '{\"noOrphans\":false, \"logicalTimes\":true}'") - ); - - unsigned int high = params[0].get_int(); - unsigned int low = params[1].get_int(); - bool fActiveOnly = false; - bool fLogicalTS = false; - - if (params.size() > 2) { - if (params[2].isObject()) { - UniValue noOrphans = find_value(params[2].get_obj(), "noOrphans"); - UniValue returnLogical = find_value(params[2].get_obj(), "logicalTimes"); - - if (noOrphans.isBool()) - fActiveOnly = noOrphans.get_bool(); - - if (returnLogical.isBool()) - fLogicalTS = returnLogical.get_bool(); - } - } - - std::vector > blockHashes; - - if (fActiveOnly) - LOCK(cs_main); - - if (!GetTimestampIndex(high, low, fActiveOnly, blockHashes)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for block hashes"); - } - - UniValue result(UniValue::VARR); - - for (std::vector >::const_iterator it=blockHashes.begin(); it!=blockHashes.end(); it++) { - if (fLogicalTS) { - UniValue item(UniValue::VOBJ); - item.push_back(Pair("blockhash", it->first.GetHex())); - item.push_back(Pair("logicalts", (int)it->second)); - result.push_back(item); - } else { - result.push_back(it->first.GetHex()); - } - } - - return result; -} - UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -1283,8 +1077,6 @@ static const CRPCCommand commands[] = { "blockchain", "getbestblockhash", &getbestblockhash, true }, { "blockchain", "getblockcount", &getblockcount, true }, { "blockchain", "getblock", &getblock, true }, - { "blockchain", "getblockdeltas", &getblockdeltas, false }, - { "blockchain", "getblockhashes", &getblockhashes, true }, { "blockchain", "getblockhash", &getblockhash, true }, { "blockchain", "getblockheader", &getblockheader, true }, { "blockchain", "getchaintips", &getchaintips, true }, diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 8ae006b99..90c70512f 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -102,15 +102,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "prioritisetransaction", 2 }, { "setban", 2 }, { "setban", 3 }, - { "getblockhashes", 0 }, - { "getblockhashes", 1 }, - { "getblockhashes", 2 }, - { "getspentinfo", 0}, - { "getaddresstxids", 0}, - { "getaddressbalance", 0}, - { "getaddressdeltas", 0}, - { "getaddressutxos", 0}, - { "getaddressmempool", 0}, }; class CRPCConvertTable diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index a364ee32a..a50abefb0 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -12,7 +12,6 @@ #include "netbase.h" #include "rpc/server.h" #include "timedata.h" -#include "txmempool.h" #include "util.h" #include "utilstrencodings.h" #ifdef ENABLE_WALLET @@ -467,534 +466,6 @@ UniValue setmocktime(const UniValue& params, bool fHelp) return NullUniValue; } -bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &address) -{ - if (type == 2) { - address = EncodeDestination(CScriptID(hash)); - } else if (type == 1) { - address = EncodeDestination(CKeyID(hash)); - } else { - return false; - } - return true; -} - -bool getAddressesFromParams(const UniValue& params, std::vector > &addresses) -{ - if (params[0].isStr()) { - CTxDestination dest = DecodeDestination(params[0].get_str()); - uint160 hashBytes; - int type = 0; - if (IsValidDestination(dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - } - addresses.push_back(std::make_pair(hashBytes, type)); - } else if (params[0].isObject()) { - - UniValue addressValues = find_value(params[0].get_obj(), "addresses"); - if (!addressValues.isArray()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Addresses is expected to be an array"); - } - - std::vector values = addressValues.getValues(); - - for (std::vector::iterator it = values.begin(); it != values.end(); ++it) { - - CTxDestination dest = DecodeDestination(it->get_str()); - uint160 hashBytes; - int type = 0; - if (IsValidDestination(dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - } - addresses.push_back(std::make_pair(hashBytes, type)); - } - } else { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - } - - return true; -} - -bool heightSort(std::pair a, - std::pair b) { - return a.second.blockHeight < b.second.blockHeight; -} - -bool timestampSort(std::pair a, - std::pair b) { - return a.second.time < b.second.time; -} - -UniValue getaddressmempool(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 1) - throw runtime_error( - "getaddressmempool\n" - "\nReturns all mempool deltas for an address (requires addressindex to be enabled).\n" - "\nArguments:\n" - "{\n" - " \"addresses\"\n" - " [\n" - " \"address\" (string) The base58check encoded address\n" - " ,...\n" - " ]\n" - "}\n" - "\nResult:\n" - "[\n" - " {\n" - " \"address\" (string) The base58check encoded address\n" - " \"txid\" (string) The related txid\n" - " \"index\" (number) The related input or output index\n" - " \"satoshis\" (number) The difference of satoshis\n" - " \"timestamp\" (number) The time the transaction entered the mempool (seconds)\n" - " \"prevtxid\" (string) The previous txid (if spending)\n" - " \"prevout\" (string) The previous transaction output index (if spending)\n" - " }\n" - "]\n" - "\nExamples:\n" - + HelpExampleCli("getaddressmempool", "'{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}'") - + HelpExampleRpc("getaddressmempool", "{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}") - ); - - std::vector > addresses; - - if (!getAddressesFromParams(params, addresses)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - } - - std::vector > indexes; - - if (!mempool.getAddressIndex(addresses, indexes)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); - } - - std::sort(indexes.begin(), indexes.end(), timestampSort); - - UniValue result(UniValue::VARR); - - for (std::vector >::iterator it = indexes.begin(); - it != indexes.end(); it++) { - - std::string address; - if (!getAddressFromIndex(it->first.type, it->first.addressBytes, address)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type"); - } - - UniValue delta(UniValue::VOBJ); - delta.push_back(Pair("address", address)); - delta.push_back(Pair("txid", it->first.txhash.GetHex())); - delta.push_back(Pair("index", (int)it->first.index)); - delta.push_back(Pair("satoshis", it->second.amount)); - delta.push_back(Pair("timestamp", it->second.time)); - if (it->second.amount < 0) { - delta.push_back(Pair("prevtxid", it->second.prevhash.GetHex())); - delta.push_back(Pair("prevout", (int)it->second.prevout)); - } - result.push_back(delta); - } - - return result; -} - -UniValue getaddressutxos(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 1) - throw runtime_error( - "getaddressutxos\n" - "\nReturns all unspent outputs for an address (requires addressindex to be enabled).\n" - "\nArguments:\n" - "{\n" - " \"addresses\"\n" - " [\n" - " \"address\" (string) The base58check encoded address\n" - " ,...\n" - " ],\n" - " \"chainInfo\" (boolean) Include chain info with results\n" - "}\n" - "\nResult\n" - "[\n" - " {\n" - " \"address\" (string) The address base58check encoded\n" - " \"txid\" (string) The output txid\n" - " \"height\" (number) The block height\n" - " \"outputIndex\" (number) The output index\n" - " \"script\" (strin) The script hex encoded\n" - " \"satoshis\" (number) The number of satoshis of the output\n" - " }\n" - "]\n" - "\nExamples:\n" - + HelpExampleCli("getaddressutxos", "'{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}'") - + HelpExampleRpc("getaddressutxos", "{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}") - ); - - bool includeChainInfo = false; - if (params[0].isObject()) { - UniValue chainInfo = find_value(params[0].get_obj(), "chainInfo"); - if (chainInfo.isBool()) { - includeChainInfo = chainInfo.get_bool(); - } - } - - std::vector > addresses; - - if (!getAddressesFromParams(params, addresses)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - } - - std::vector > unspentOutputs; - - for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) { - if (!GetAddressUnspent((*it).first, (*it).second, unspentOutputs)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); - } - } - - std::sort(unspentOutputs.begin(), unspentOutputs.end(), heightSort); - - UniValue utxos(UniValue::VARR); - - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) { - UniValue output(UniValue::VOBJ); - std::string address; - if (!getAddressFromIndex(it->first.type, it->first.hashBytes, address)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type"); - } - - output.push_back(Pair("address", address)); - output.push_back(Pair("txid", it->first.txhash.GetHex())); - output.push_back(Pair("outputIndex", (int)it->first.index)); - output.push_back(Pair("script", HexStr(it->second.script.begin(), it->second.script.end()))); - output.push_back(Pair("satoshis", it->second.satoshis)); - output.push_back(Pair("height", it->second.blockHeight)); - output.push_back(Pair("txtime", it->second.nTime)); - utxos.push_back(output); - } - - if (includeChainInfo) { - UniValue result(UniValue::VOBJ); - result.push_back(Pair("utxos", utxos)); - - LOCK(cs_main); - result.push_back(Pair("hash", chainActive.Tip()->GetBlockHash().GetHex())); - result.push_back(Pair("height", (int)chainActive.Height())); - return result; - } else { - return utxos; - } -} - -UniValue getaddressdeltas(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 1 || !params[0].isObject()) - throw runtime_error( - "getaddressdeltas\n" - "\nReturns all changes for an address (requires addressindex to be enabled).\n" - "\nArguments:\n" - "{\n" - " \"addresses\"\n" - " [\n" - " \"address\" (string) The base58check encoded address\n" - " ,...\n" - " ]\n" - " \"start\" (number) The start block height\n" - " \"end\" (number) The end block height\n" - " \"chainInfo\" (boolean) Include chain info in results, only applies if start and end specified\n" - "}\n" - "\nResult:\n" - "[\n" - " {\n" - " \"satoshis\" (number) The difference of satoshis\n" - " \"txid\" (string) The related txid\n" - " \"index\" (number) The related input or output index\n" - " \"height\" (number) The block height\n" - " \"address\" (string) The base58check encoded address\n" - " }\n" - "]\n" - "\nExamples:\n" - + HelpExampleCli("getaddressdeltas", "'{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}'") - + HelpExampleRpc("getaddressdeltas", "{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}") - ); - - - UniValue startValue = find_value(params[0].get_obj(), "start"); - UniValue endValue = find_value(params[0].get_obj(), "end"); - - UniValue chainInfo = find_value(params[0].get_obj(), "chainInfo"); - bool includeChainInfo = false; - if (chainInfo.isBool()) { - includeChainInfo = chainInfo.get_bool(); - } - - int start = 0; - int end = 0; - - if (startValue.isNum() && endValue.isNum()) { - start = startValue.get_int(); - end = endValue.get_int(); - if (start <= 0 || end <= 0) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Start and end is expected to be greater than zero"); - } - if (end < start) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "End value is expected to be greater than start"); - } - } - - std::vector > addresses; - - if (!getAddressesFromParams(params, addresses)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - } - - std::vector > addressIndex; - - for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) { - if (start > 0 && end > 0) { - if (!GetAddressIndex((*it).first, (*it).second, addressIndex, start, end)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); - } - } else { - if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); - } - } - } - - UniValue deltas(UniValue::VARR); - - for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { - std::string address; - if (!getAddressFromIndex(it->first.type, it->first.hashBytes, address)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type"); - } - - UniValue delta(UniValue::VOBJ); - delta.push_back(Pair("satoshis", it->second)); - delta.push_back(Pair("txid", it->first.txhash.GetHex())); - delta.push_back(Pair("index", (int)it->first.index)); - delta.push_back(Pair("blockindex", (int)it->first.txindex)); - delta.push_back(Pair("height", it->first.blockHeight)); - delta.push_back(Pair("address", address)); - deltas.push_back(delta); - } - - UniValue result(UniValue::VOBJ); - - if (includeChainInfo && start > 0 && end > 0) { - LOCK(cs_main); - - if (start > chainActive.Height() || end > chainActive.Height()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Start or end is outside chain range"); - } - - CBlockIndex* startIndex = chainActive[start]; - CBlockIndex* endIndex = chainActive[end]; - - UniValue startInfo(UniValue::VOBJ); - UniValue endInfo(UniValue::VOBJ); - - startInfo.push_back(Pair("hash", startIndex->GetBlockHash().GetHex())); - startInfo.push_back(Pair("height", start)); - - endInfo.push_back(Pair("hash", endIndex->GetBlockHash().GetHex())); - endInfo.push_back(Pair("height", end)); - - result.push_back(Pair("deltas", deltas)); - result.push_back(Pair("start", startInfo)); - result.push_back(Pair("end", endInfo)); - - return result; - } else { - return deltas; - } -} - -UniValue getaddressbalance(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 1) - throw runtime_error( - "getaddressbalance\n" - "\nReturns the balance for an address(es) (requires addressindex to be enabled).\n" - "\nArguments:\n" - "{\n" - " \"addresses\"\n" - " [\n" - " \"address\" (string) The base58check encoded address\n" - " ,...\n" - " ]\n" - "}\n" - "\nResult:\n" - "{\n" - " \"balance\" (string) The current balance in satoshis\n" - " \"received\" (string) The total number of satoshis received (including change)\n" - "}\n" - "\nExamples:\n" - + HelpExampleCli("getaddressbalance", "'{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}'") - + HelpExampleRpc("getaddressbalance", "{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}") - ); - - std::vector > addresses; - - if (!getAddressesFromParams(params, addresses)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - } - - std::vector > addressIndex; - - for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) { - if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); - } - } - - CAmount balance = 0; - CAmount received = 0; - - for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { - if (it->second > 0) { - received += it->second; - } - balance += it->second; - } - - UniValue result(UniValue::VOBJ); - result.push_back(Pair("balance", balance)); - result.push_back(Pair("received", received)); - - return result; - -} - -UniValue getaddresstxids(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 1) - throw runtime_error( - "getaddresstxids\n" - "\nReturns the txids for an address(es) (requires addressindex to be enabled).\n" - "\nArguments:\n" - "{\n" - " \"addresses\"\n" - " [\n" - " \"address\" (string) The base58check encoded address\n" - " ,...\n" - " ]\n" - " \"start\" (number) The start block height\n" - " \"end\" (number) The end block height\n" - "}\n" - "\nResult:\n" - "[\n" - " \"transactionid\" (string) The transaction id\n" - " ,...\n" - "]\n" - "\nExamples:\n" - + HelpExampleCli("getaddresstxids", "'{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}'") - + HelpExampleRpc("getaddresstxids", "{\"addresses\": [\"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX\"]}") - ); - - std::vector > addresses; - - if (!getAddressesFromParams(params, addresses)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - } - - int start = 0; - int end = 0; - if (params[0].isObject()) { - UniValue startValue = find_value(params[0].get_obj(), "start"); - UniValue endValue = find_value(params[0].get_obj(), "end"); - if (startValue.isNum() && endValue.isNum()) { - start = startValue.get_int(); - end = endValue.get_int(); - } - } - - std::vector > addressIndex; - - for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) { - if (start > 0 && end > 0) { - if (!GetAddressIndex((*it).first, (*it).second, addressIndex, start, end)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); - } - } else { - if (!GetAddressIndex((*it).first, (*it).second, addressIndex)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address"); - } - } - } - - std::set > txids; - UniValue result(UniValue::VARR); - - for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { - int height = it->first.blockHeight; - std::string txid = it->first.txhash.GetHex(); - - if (addresses.size() > 1) { - txids.insert(std::make_pair(height, txid)); - } else { - if (txids.insert(std::make_pair(height, txid)).second) { - result.push_back(txid); - } - } - } - - if (addresses.size() > 1) { - for (std::set >::const_iterator it=txids.begin(); it!=txids.end(); it++) { - result.push_back(it->second); - } - } - - return result; - -} - -UniValue getspentinfo(const UniValue& params, bool fHelp) -{ - - if (fHelp || params.size() != 1 || !params[0].isObject()) - throw runtime_error( - "getspentinfo\n" - "\nReturns the txid and index where an output is spent.\n" - "\nArguments:\n" - "{\n" - " \"txid\" (string) The hex string of the txid\n" - " \"index\" (number) The start block height\n" - "}\n" - "\nResult:\n" - "{\n" - " \"txid\" (string) The transaction id\n" - " \"index\" (number) The spending input index\n" - " ,...\n" - "}\n" - "\nExamples:\n" - + HelpExampleCli("getspentinfo", "'{\"txid\": \"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9\", \"index\": 0}'") - + HelpExampleRpc("getspentinfo", "{\"txid\": \"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9\", \"index\": 0}") - ); - - UniValue txidValue = find_value(params[0].get_obj(), "txid"); - UniValue indexValue = find_value(params[0].get_obj(), "index"); - - if (!txidValue.isStr() || !indexValue.isNum()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid txid or index"); - } - - uint256 txid = ParseHashV(txidValue, "txid"); - int outputIndex = indexValue.get_int(); - - CSpentIndexKey key(txid, outputIndex); - CSpentIndexValue value; - - if (!GetSpentIndex(key, value)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to get spent info"); - } - - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("txid", value.txid.GetHex())); - obj.push_back(Pair("index", (int)value.inputIndex)); - obj.push_back(Pair("height", value.blockHeight)); - - return obj; -} - static const CRPCCommand commands[] = { // category name actor (function) okSafeMode // --------------------- ------------------------ ----------------------- ---------- @@ -1003,14 +474,6 @@ static const CRPCCommand commands[] = { "util", "createmultisig", &createmultisig, true }, { "util", "verifymessage", &verifymessage, true }, { "util", "signmessagewithprivkey", &signmessagewithprivkey, true }, - { "util", "getspentinfo", &getspentinfo, false }, - - /* Address index */ - { "addressindex", "getaddressmempool", &getaddressmempool, true }, - { "addressindex", "getaddressutxos", &getaddressutxos, false }, - { "addressindex", "getaddressdeltas", &getaddressdeltas, false }, - { "addressindex", "getaddresstxids", &getaddresstxids, false }, - { "addressindex", "getaddressbalance", &getaddressbalance, false }, /* Not shown in help */ { "hidden", "setmocktime", &setmocktime, true }, diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 83ce44a96..466801332 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -63,91 +63,9 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud out.push_back(Pair("addresses", a)); } -void TxToJSONExpanded(const CTransaction& tx, const uint256 hashBlock, UniValue& entry, - int nHeight = 0, int nConfirmations = 0, int nBlockTime = 0) -{ - - uint256 txid = tx.GetHash(); - entry.push_back(Pair("txid", txid.GetHex())); - entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION))); - entry.push_back(Pair("version", tx.nVersion)); - entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); - UniValue vin(UniValue::VARR); - BOOST_FOREACH(const CTxIn& txin, tx.vin) { - UniValue in(UniValue::VOBJ); - if (tx.IsCoinBase()) - in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); - else { - in.push_back(Pair("txid", txin.prevout.hash.GetHex())); - in.push_back(Pair("vout", (int64_t)txin.prevout.n)); - UniValue o(UniValue::VOBJ); - o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true))); - o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); - in.push_back(Pair("scriptSig", o)); - - // Add address and value info if spentindex enabled - CSpentIndexValue spentInfo; - CSpentIndexKey spentKey(txin.prevout.hash, txin.prevout.n); - if (GetSpentIndex(spentKey, spentInfo)) { - in.push_back(Pair("value", ValueFromAmount(spentInfo.satoshis))); - in.push_back(Pair("valueSat", spentInfo.satoshis)); - if (spentInfo.addressType == 1) { - in.push_back(Pair("address", EncodeDestination(CKeyID(spentInfo.addressHash)))); - } else if (spentInfo.addressType == 2) { - in.push_back(Pair("address", EncodeDestination(CScriptID(spentInfo.addressHash)))); - } - } - - } - in.push_back(Pair("sequence", (int64_t)txin.nSequence)); - vin.push_back(in); - } - entry.push_back(Pair("vin", vin)); - UniValue vout(UniValue::VARR); - for (unsigned int i = 0; i < tx.vout.size(); i++) { - const CTxOut& txout = tx.vout[i]; - UniValue out(UniValue::VOBJ); - out.push_back(Pair("value", ValueFromAmount(txout.nValue))); - out.push_back(Pair("valueSat", txout.nValue)); - out.push_back(Pair("n", (int64_t)i)); - UniValue o(UniValue::VOBJ); - ScriptPubKeyToJSON(txout.scriptPubKey, o, true); - out.push_back(Pair("scriptPubKey", o)); - - // Add spent information if spentindex is enabled - CSpentIndexValue spentInfo; - CSpentIndexKey spentKey(txid, i); - if (GetSpentIndex(spentKey, spentInfo)) { - out.push_back(Pair("spentTxId", spentInfo.txid.GetHex())); - out.push_back(Pair("spentIndex", (int)spentInfo.inputIndex)); - out.push_back(Pair("spentHeight", spentInfo.blockHeight)); - } - - vout.push_back(out); - } - entry.push_back(Pair("vout", vout)); - - if (!hashBlock.IsNull()) { - entry.push_back(Pair("blockhash", hashBlock.GetHex())); - - if (nConfirmations > 0) { - entry.push_back(Pair("height", nHeight)); - entry.push_back(Pair("confirmations", nConfirmations)); - entry.push_back(Pair("time", nBlockTime)); - entry.push_back(Pair("blocktime", nBlockTime)); - } else { - entry.push_back(Pair("height", -1)); - entry.push_back(Pair("confirmations", 0)); - } - } - -} - void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { - - uint256 txid = tx.GetHash(); - entry.push_back(Pair("txid", txid.GetHex())); + entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION))); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); @@ -175,7 +93,6 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) const CTxOut& txout = tx.vout[i]; UniValue out(UniValue::VOBJ); out.push_back(Pair("value", ValueFromAmount(txout.nValue))); - out.push_back(Pair("valueSat", txout.nValue)); out.push_back(Pair("n", (int64_t)i)); UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(txout.scriptPubKey, o, true); @@ -190,14 +107,12 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; if (chainActive.Contains(pindex)) { - entry.push_back(Pair("height", pindex->nHeight)); entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight)); entry.push_back(Pair("time", pindex->GetBlockTime())); entry.push_back(Pair("blocktime", pindex->GetBlockTime())); - } else { - entry.push_back(Pair("height", -1)); - entry.push_back(Pair("confirmations", 0)); } + else + entry.push_back(Pair("confirmations", 0)); } } } @@ -269,6 +184,8 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1") ); + LOCK(cs_main); + uint256 hash = ParseHashV(params[0], "parameter 1"); bool fVerbose = false; @@ -276,31 +193,9 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) fVerbose = (params[1].get_int() != 0); CTransaction tx; - uint256 hashBlock; - int nHeight = 0; - int nConfirmations = 0; - int nBlockTime = 0; - - { - LOCK(cs_main); - if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); - - BlockMap::iterator mi = mapBlockIndex.find(hashBlock); - if (mi != mapBlockIndex.end() && (*mi).second) { - CBlockIndex* pindex = (*mi).second; - if (chainActive.Contains(pindex)) { - nHeight = pindex->nHeight; - nConfirmations = 1 + chainActive.Height() - pindex->nHeight; - nBlockTime = pindex->GetBlockTime(); - } else { - nHeight = -1; - nConfirmations = 0; - nBlockTime = pindex->GetBlockTime(); - } - } - } + if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); string strHex = EncodeHexTx(tx); @@ -309,8 +204,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) UniValue result(UniValue::VOBJ); result.push_back(Pair("hex", strHex)); - TxToJSONExpanded(tx, hashBlock, result, nHeight, nConfirmations, nBlockTime); - + TxToJSON(tx, hashBlock, result); return result; } diff --git a/src/script/script.cpp b/src/script/script.cpp index e684b4e47..226e960eb 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -201,17 +201,6 @@ unsigned int CScript::GetSigOpCount(const CScript& scriptSig) const return subscript.GetSigOpCount(true); } -bool CScript::IsPayToPublicKeyHash() const -{ - // Extra-fast test for pay-to-pubkey-hash CScripts: - return (this->size() == 25 && - (*this)[0] == OP_DUP && - (*this)[1] == OP_HASH160 && - (*this)[2] == 0x14 && - (*this)[23] == OP_EQUALVERIFY && - (*this)[24] == OP_CHECKSIG); -} - bool CScript::IsPayToScriptHash() const { // Extra-fast test for pay-to-script-hash CScripts: @@ -221,13 +210,11 @@ bool CScript::IsPayToScriptHash() const (*this)[22] == OP_EQUAL); } - - bool CScript::IsPayToPublicKey() const { // Extra-fast test for pay-to-pubkey CScripts: return (this->size() == 35 && - (*this)[0] == 0x21 && + (*this)[0] == 0x21 && (*this)[34] == OP_CHECKSIG); } diff --git a/src/script/script.h b/src/script/script.h index b24da9c47..004362d36 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -633,10 +633,7 @@ public: */ unsigned int GetSigOpCount(const CScript& scriptSig) const; - bool IsPayToPublicKeyHash() const; - bool IsPayToScriptHash() const; - bool IsPayToPublicKey() const; /** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */ diff --git a/src/serialize.h b/src/serialize.h index 3fa23e27d..378ed3907 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -91,11 +91,6 @@ template inline void ser_writedata32(Stream &s, uint32_t obj) obj = htole32(obj); s.write((char*)&obj, 4); } -template inline void ser_writedata32be(Stream &s, uint32_t obj) -{ - obj = htobe32(obj); - s.write((char*)&obj, 4); -} template inline void ser_writedata64(Stream &s, uint64_t obj) { obj = htole64(obj); @@ -119,12 +114,6 @@ template inline uint32_t ser_readdata32(Stream &s) s.read((char*)&obj, 4); return le32toh(obj); } -template inline uint32_t ser_readdata32be(Stream &s) -{ - uint32_t obj; - s.read((char*)&obj, 4); - return be32toh(obj); -} template inline uint64_t ser_readdata64(Stream &s) { uint64_t obj; diff --git a/src/spentindex.h b/src/spentindex.h deleted file mode 100644 index bd5da45d6..000000000 --- a/src/spentindex.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_SPENTINDEX_H -#define BITCOIN_SPENTINDEX_H - -#include "uint256.h" -#include "amount.h" - -struct CSpentIndexKey { - uint256 txid; - unsigned int outputIndex; - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(txid); - READWRITE(outputIndex); - } - - CSpentIndexKey(uint256 t, unsigned int i) { - txid = t; - outputIndex = i; - } - - CSpentIndexKey() { - SetNull(); - } - - void SetNull() { - txid.SetNull(); - outputIndex = 0; - } - -}; - -struct CSpentIndexValue { - uint256 txid; - unsigned int inputIndex; - int blockHeight; - CAmount satoshis; - int addressType; - uint160 addressHash; - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(txid); - READWRITE(inputIndex); - READWRITE(blockHeight); - READWRITE(satoshis); - READWRITE(addressType); - READWRITE(addressHash); - } - - CSpentIndexValue(uint256 t, unsigned int i, int h, CAmount s, int type, uint160 a) { - txid = t; - inputIndex = i; - blockHeight = h; - satoshis = s; - addressType = type; - addressHash = a; - } - - CSpentIndexValue() { - SetNull(); - } - - void SetNull() { - txid.SetNull(); - inputIndex = 0; - blockHeight = 0; - satoshis = 0; - addressType = 0; - addressHash.SetNull(); - } - - bool IsNull() const { - return txid.IsNull(); - } -}; - -struct CSpentIndexKeyCompare -{ - bool operator()(const CSpentIndexKey& a, const CSpentIndexKey& b) const { - if (a.txid == b.txid) { - return a.outputIndex < b.outputIndex; - } else { - return a.txid < b.txid; - } - } -}; - -#endif // BITCOIN_SPENTINDEX_H diff --git a/src/test/data/wallet.dat b/src/test/data/wallet.dat deleted file mode 100644 index d1352c06731a3b74b642eeef2dc5acaaa8a7b025..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI&cT5vu6aet=JFb+{CAi}%N(@23Dg=q*s0=}kiA+&Zsi~oYR4ZsCYOEq6;;5wo z!~p^SaDfwKh%-@3z&!{xYDE+2 zg%0Ti7UIx@e$>)AK*)-I&Il1TPLyv%1ht#pVU=J+{Eru@ZJi;a9?dzwZ-GY;009sH z0T2KI5C8!X009sH0T2Lz-WH&Hb!NX#Afpho+J#2p&)ezq6j2NG|Fi@I2!H?xfB*=9 z00@8p2!H?xfB*>eT>-MQ(pW4q_owIX|1|$^p3^sfA`vy{PXGVweFNtG zVGRNx00JNY0w4eaAOHd&00JNY0wB;k0(Ae+?AHgNTO7=C;=0(*5c&!{_+C5@!3(|< z?;&@%?JZ6cH=cV?m?qrE-@^YOd`I0Q009CZ00JNY0w4eaAn^YM<{|9(2&0D6$>H?D zC8S-%`hg+j^Rv0{vR$QGt6W{#be1yr>3Pr5>+OQ4b$70n30%KB?)mS3kE6a9%9Z|4sSlk(d z&%`HLlJ{eVmWJI3+!;3cWsYjQShbaUtJuYw?VKD?Jr!fZ0h#_DUrnZt@nUNdBNDSo z2Vz6Tip`(&WhX;(q}u8oTsD#2QR`amR1?vvS~RGAaOUsXzLpl~>k9*Nrd+fs|;VPi&VZ36z`ezSbySvTFs7Byy6(ifw zBd$Dz=}YdnUEdX&jWC~L6 zcE-=mpf)^D*014|HQf_1YQa*fZn$>U!ka(VLJ#Ecss(d?2{|CZ`hr8~>}7-8jKk;H zD_s&QPDQmSy<(#09KYt)UvAtz?#jin!AU3h&Z)6;7i1W)oxbT@VSgS!k26HO@@WdA z7U&|TgINpgu&kzM+h%_D{PIC3$QbLLp7K=F$ZB=4ZXKCibU0*T->L;m7?B6Zg}cVK zor|u>`@~UBsW>)2KW3ZEeb=R`OM5#i7rbTEf~8d5aQ$a3^gw=U&Y%8|KsMCx%{rNK Jty~d@z5y4K>5BjW diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 10db482e5..081d57831 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -47,49 +47,6 @@ BOOST_AUTO_TEST_CASE(dbwrapper) } } -BOOST_AUTO_TEST_CASE(dbwrapper_compression) -{ - // Perform tests both with compression and without - for (int i = 0; i < 2; i++) { - bool compression = (bool)i; - path ph = temp_directory_path() / unique_path(); - CDBWrapper dbw(ph, (1 << 20), true, false, false, compression); - char key = 'k'; - uint256 in = GetRandHash(); - uint256 res; - - BOOST_CHECK(dbw.Write(key, in)); - BOOST_CHECK(dbw.Read(key, res)); - BOOST_CHECK_EQUAL(res.ToString(), in.ToString()); - } -} - -BOOST_AUTO_TEST_CASE(dbwrapper_maxopenfiles_64) -{ - path ph = temp_directory_path() / unique_path(); - CDBWrapper dbw(ph, (1 << 20), true, false, false, false, 64); - char key = 'k'; - uint256 in = GetRandHash(); - uint256 res; - - BOOST_CHECK(dbw.Write(key, in)); - BOOST_CHECK(dbw.Read(key, res)); - BOOST_CHECK_EQUAL(res.ToString(), in.ToString()); -} - -BOOST_AUTO_TEST_CASE(dbwrapper_maxopenfiles_1000) -{ - path ph = temp_directory_path() / unique_path(); - CDBWrapper dbw(ph, (1 << 20), true, false, false, false, 1000); - char key = 'k'; - uint256 in = GetRandHash(); - uint256 res; - - BOOST_CHECK(dbw.Write(key, in)); - BOOST_CHECK(dbw.Read(key, res)); - BOOST_CHECK_EQUAL(res.ToString(), in.ToString()); -} - // Test batch operations BOOST_AUTO_TEST_CASE(dbwrapper_batch) { diff --git a/src/test/script_P2PKH_tests.cpp b/src/test/script_P2PKH_tests.cpp deleted file mode 100644 index 3a7dc1660..000000000 --- a/src/test/script_P2PKH_tests.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2012-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. - -#include "script/script.h" -#include "test/test_bitcoin.h" - -#include - -using namespace std; - -BOOST_FIXTURE_TEST_SUITE(script_P2PKH_tests, BasicTestingSetup) - -BOOST_AUTO_TEST_CASE(IsPayToPublicKeyHash) -{ - // Test CScript::IsPayToPublicKeyHash() - uint160 dummy; - CScript p2pkh; - p2pkh << OP_DUP << OP_HASH160 << ToByteVector(dummy) << OP_EQUALVERIFY << OP_CHECKSIG; - BOOST_CHECK(p2pkh.IsPayToPublicKeyHash()); - - static const unsigned char direct[] = { - OP_DUP, OP_HASH160, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUALVERIFY, OP_CHECKSIG - }; - BOOST_CHECK(CScript(direct, direct+sizeof(direct)).IsPayToPublicKeyHash()); - - static const unsigned char notp2pkh1[] = { - OP_DUP, OP_HASH160, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUALVERIFY, OP_CHECKSIG, OP_CHECKSIG - }; - BOOST_CHECK(!CScript(notp2pkh1, notp2pkh1+sizeof(notp2pkh1)).IsPayToPublicKeyHash()); - - static const unsigned char p2sh[] = { - OP_HASH160, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL - }; - BOOST_CHECK(!CScript(p2sh, p2sh+sizeof(p2sh)).IsPayToPublicKeyHash()); - - static const unsigned char extra[] = { - OP_DUP, OP_HASH160, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUALVERIFY, OP_CHECKSIG, OP_CHECKSIG - }; - BOOST_CHECK(!CScript(extra, extra+sizeof(extra)).IsPayToPublicKeyHash()); - - static const unsigned char missing[] = { - OP_HASH160, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUALVERIFY, OP_CHECKSIG, OP_RETURN - }; - BOOST_CHECK(!CScript(missing, missing+sizeof(missing)).IsPayToPublicKeyHash()); - - static const unsigned char missing2[] = { - OP_DUP, OP_HASH160, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - }; - BOOST_CHECK(!CScript(missing2, missing2+sizeof(missing)).IsPayToPublicKeyHash()); - - static const unsigned char tooshort[] = { - OP_DUP, OP_HASH160, 2, 0,0, OP_EQUALVERIFY, OP_CHECKSIG - }; - BOOST_CHECK(!CScript(tooshort, tooshort+sizeof(direct)).IsPayToPublicKeyHash()); - -} - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/wallet-utility.py b/src/test/wallet-utility.py deleted file mode 100755 index b853a227e..000000000 --- a/src/test/wallet-utility.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/python -# Copyright 2014 BitPay, Inc. -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -import subprocess -import os -import json -import sys -import buildenv -import shutil - -def assert_equal(thing1, thing2): - if thing1 != thing2: - raise AssertionError("%s != %s"%(str(thing1),str(thing2))) - -if __name__ == '__main__': - datadir = os.environ["srcdir"] + "/test/data" - execprog = './wallet-utility' + buildenv.exeext - execargs = '-datadir=' + datadir - execrun = execprog + ' ' + execargs - - proc = subprocess.Popen(execrun, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=True) - try: - outs = proc.communicate() - except OSError: - print("OSError, Failed to execute " + execprog) - sys.exit(1) - - output = json.loads(outs[0]) - - assert_equal(output[0], "13EngsxkRi7SJPPqCyJsKf34U8FoX9E9Av") - assert_equal(output[1], "1FKCLGTpPeYBUqfNxktck8k5nqxB8sjim8") - assert_equal(output[2], "13cdtE9tnNeXCZJ8KQ5WELgEmLSBLnr48F") - - execargs = '-datadir=' + datadir + ' -dumppass' - execrun = execprog + ' ' + execargs - - proc = subprocess.Popen(execrun, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=True) - try: - outs = proc.communicate() - except OSError: - print("OSError, Failed to execute " + execprog) - sys.exit(1) - - output = json.loads(outs[0]) - - assert_equal(output[0]['addr'], "13EngsxkRi7SJPPqCyJsKf34U8FoX9E9Av") - assert_equal(output[0]['pkey'], "5Jz5BWE2WQxp1hGqDZeisQFV1mRFR2AVBAgiXCbNcZyXNjD9aUd") - assert_equal(output[1]['addr'], "1FKCLGTpPeYBUqfNxktck8k5nqxB8sjim8") - assert_equal(output[1]['pkey'], "5HsX2b3v2GjngYQ5ZM4mLp2b2apw6aMNVaPELV1YmpiYR1S4jzc") - assert_equal(output[2]['addr'], "13cdtE9tnNeXCZJ8KQ5WELgEmLSBLnr48F") - assert_equal(output[2]['pkey'], "5KCWAs1wX2ESiL4PfDR8XYVSSETHFd2jaRGxt1QdanBFTit4XcH") - - if os.path.exists(datadir + '/database'): - if os.path.isdir(datadir + '/database'): - shutil.rmtree(datadir + '/database') - - if os.path.exists(datadir + '/db.log'): - os.remove(datadir + '/db.log') - sys.exit(0) diff --git a/src/txdb.cpp b/src/txdb.cpp index 0689ac1f4..f45dfd2be 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -21,11 +21,6 @@ using namespace std; static const char DB_COINS = 'c'; static const char DB_BLOCK_FILES = 'f'; static const char DB_TXINDEX = 't'; -static const char DB_ADDRESSINDEX = 'a'; -static const char DB_ADDRESSUNSPENTINDEX = 'u'; -static const char DB_TIMESTAMPINDEX = 's'; -static const char DB_BLOCKHASHINDEX = 'z'; -static const char DB_SPENTINDEX = 'p'; static const char DB_BLOCK_INDEX = 'b'; static const char DB_BEST_BLOCK = 'B'; @@ -34,7 +29,7 @@ static const char DB_REINDEX_FLAG = 'R'; static const char DB_LAST_BLOCK = 'l'; -CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe, true, false, 64) +CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe, true) { } @@ -76,7 +71,7 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return db.WriteBatch(batch); } -CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe, bool compression, int maxOpenFiles) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe, false, compression, maxOpenFiles) { +CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe, false) { } bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) { @@ -166,156 +161,6 @@ bool CBlockTreeDB::WriteTxIndex(const std::vector return WriteBatch(batch); } -bool CBlockTreeDB::ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) { - return Read(make_pair(DB_SPENTINDEX, key), value); -} - -bool CBlockTreeDB::UpdateSpentIndex(const std::vector >&vect) { - CDBBatch batch(*this); - for (std::vector >::const_iterator it=vect.begin(); it!=vect.end(); it++) { - if (it->second.IsNull()) { - batch.Erase(make_pair(DB_SPENTINDEX, it->first)); - } else { - batch.Write(make_pair(DB_SPENTINDEX, it->first), it->second); - } - } - return WriteBatch(batch); -} - -bool CBlockTreeDB::UpdateAddressUnspentIndex(const std::vector >&vect) { - CDBBatch batch(*this); - for (std::vector >::const_iterator it=vect.begin(); it!=vect.end(); it++) { - if (it->second.IsNull()) { - batch.Erase(make_pair(DB_ADDRESSUNSPENTINDEX, it->first)); - } else { - batch.Write(make_pair(DB_ADDRESSUNSPENTINDEX, it->first), it->second); - } - } - return WriteBatch(batch); -} - -bool CBlockTreeDB::ReadAddressUnspentIndex(uint160 addressHash, int type, - std::vector > &unspentOutputs) { - boost::scoped_ptr pcursor(NewIterator()); - - pcursor->Seek(make_pair(DB_ADDRESSUNSPENTINDEX, CAddressIndexIteratorKey(type, addressHash))); - - while (pcursor->Valid()) { - boost::this_thread::interruption_point(); - std::pair key; - if (pcursor->GetKey(key) && key.first == DB_ADDRESSUNSPENTINDEX && key.second.hashBytes == addressHash) { - CAddressUnspentValue nValue; - if (pcursor->GetValue(nValue)) { - unspentOutputs.push_back(make_pair(key.second, nValue)); - pcursor->Next(); - } else { - return error("failed to get address unspent value"); - } - } else { - break; - } - } - - return true; -} - -bool CBlockTreeDB::WriteAddressIndex(const std::vector >&vect) { - CDBBatch batch(*this); - for (std::vector >::const_iterator it=vect.begin(); it!=vect.end(); it++) - batch.Write(make_pair(DB_ADDRESSINDEX, it->first), it->second); - return WriteBatch(batch); -} - -bool CBlockTreeDB::EraseAddressIndex(const std::vector >&vect) { - CDBBatch batch(*this); - for (std::vector >::const_iterator it=vect.begin(); it!=vect.end(); it++) - batch.Erase(make_pair(DB_ADDRESSINDEX, it->first)); - return WriteBatch(batch); -} - -bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, int type, - std::vector > &addressIndex, - int start, int end) { - - boost::scoped_ptr pcursor(NewIterator()); - - if (start > 0 && end > 0) { - pcursor->Seek(make_pair(DB_ADDRESSINDEX, CAddressIndexIteratorHeightKey(type, addressHash, start))); - } else { - pcursor->Seek(make_pair(DB_ADDRESSINDEX, CAddressIndexIteratorKey(type, addressHash))); - } - - while (pcursor->Valid()) { - boost::this_thread::interruption_point(); - std::pair key; - if (pcursor->GetKey(key) && key.first == DB_ADDRESSINDEX && key.second.hashBytes == addressHash) { - if (end > 0 && key.second.blockHeight > end) { - break; - } - CAmount nValue; - if (pcursor->GetValue(nValue)) { - addressIndex.push_back(make_pair(key.second, nValue)); - pcursor->Next(); - } else { - return error("failed to get address index value"); - } - } else { - break; - } - } - - return true; -} - -bool CBlockTreeDB::WriteTimestampIndex(const CTimestampIndexKey ×tampIndex) { - CDBBatch batch(*this); - batch.Write(make_pair(DB_TIMESTAMPINDEX, timestampIndex), 0); - return WriteBatch(batch); -} - -bool CBlockTreeDB::ReadTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector > &hashes) { - - boost::scoped_ptr pcursor(NewIterator()); - - pcursor->Seek(make_pair(DB_TIMESTAMPINDEX, CTimestampIndexIteratorKey(low))); - - while (pcursor->Valid()) { - boost::this_thread::interruption_point(); - std::pair key; - if (pcursor->GetKey(key) && key.first == DB_TIMESTAMPINDEX && key.second.timestamp < high) { - if (fActiveOnly) { - if (blockOnchainActive(key.second.blockHash)) { - hashes.push_back(std::make_pair(key.second.blockHash, key.second.timestamp)); - } - } else { - hashes.push_back(std::make_pair(key.second.blockHash, key.second.timestamp)); - } - - pcursor->Next(); - } else { - break; - } - } - - return true; -} - -bool CBlockTreeDB::WriteTimestampBlockIndex(const CTimestampBlockIndexKey &blockhashIndex, const CTimestampBlockIndexValue &logicalts) { - CDBBatch batch(*this); - batch.Write(make_pair(DB_BLOCKHASHINDEX, blockhashIndex), logicalts); - return WriteBatch(batch); -} - -bool CBlockTreeDB::ReadTimestampBlockIndex(const uint256 &hash, unsigned int <imestamp) { - - CTimestampBlockIndexValue(lts); - if (!Read(std::make_pair(DB_BLOCKHASHINDEX, hash), lts)) - return false; - - ltimestamp = lts.ltimestamp; - return true; -} - bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) { return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0'); } @@ -328,16 +173,6 @@ bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) { return true; } -bool CBlockTreeDB::blockOnchainActive(const uint256 &hash) { - CBlockIndex* pblockindex = mapBlockIndex[hash]; - - if (!chainActive.Contains(pblockindex)) { - return false; - } - - return true; -} - bool CBlockTreeDB::LoadBlockIndexGuts() { boost::scoped_ptr pcursor(NewIterator()); diff --git a/src/txdb.h b/src/txdb.h index d3085163f..749802f0e 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -17,17 +17,6 @@ class CBlockFileInfo; class CBlockIndex; struct CDiskTxPos; -struct CAddressUnspentKey; -struct CAddressUnspentValue; -struct CAddressIndexKey; -struct CAddressIndexIteratorKey; -struct CAddressIndexIteratorHeightKey; -struct CTimestampIndexKey; -struct CTimestampIndexIteratorKey; -struct CTimestampBlockIndexKey; -struct CTimestampBlockIndexValue; -struct CSpentIndexKey; -struct CSpentIndexValue; class uint256; //! -dbcache default (MiB) @@ -80,7 +69,7 @@ private: class CBlockTreeDB : public CDBWrapper { public: - CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false, bool compression = true, int maxOpenFiles = 1000); + CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); private: CBlockTreeDB(const CBlockTreeDB&); void operator=(const CBlockTreeDB&); @@ -92,24 +81,9 @@ public: bool ReadReindexing(bool &fReindex); bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos); bool WriteTxIndex(const std::vector > &list); - bool ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value); - bool UpdateSpentIndex(const std::vector >&vect); - bool UpdateAddressUnspentIndex(const std::vector >&vect); - bool ReadAddressUnspentIndex(uint160 addressHash, int type, - std::vector > &vect); - bool WriteAddressIndex(const std::vector > &vect); - bool EraseAddressIndex(const std::vector > &vect); - bool ReadAddressIndex(uint160 addressHash, int type, - std::vector > &addressIndex, - int start = 0, int end = 0); - bool WriteTimestampIndex(const CTimestampIndexKey ×tampIndex); - bool ReadTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector > &vect); - bool WriteTimestampBlockIndex(const CTimestampBlockIndexKey &blockhashIndex, const CTimestampBlockIndexValue &logicalts); - bool ReadTimestampBlockIndex(const uint256 &hash, unsigned int &logicalTS); bool WriteFlag(const std::string &name, bool fValue); bool ReadFlag(const std::string &name, bool &fValue); bool LoadBlockIndexGuts(); - bool blockOnchainActive(const uint256 &hash); }; #endif // BITCOIN_TXDB_H diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 6a0f11bc3..4c4c8cd7a 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -441,145 +441,6 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, return true; } -void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view) -{ - LOCK(cs); - const CTransaction& tx = entry.GetTx(); - std::vector inserted; - - uint256 txhash = tx.GetHash(); - for (unsigned int j = 0; j < tx.vin.size(); j++) { - const CTxIn input = tx.vin[j]; - const CTxOut &prevout = view.GetOutputFor(input); - if (prevout.scriptPubKey.IsPayToScriptHash()) { - vector hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22); - CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, j, 1); - CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n); - mapAddress.insert(make_pair(key, delta)); - inserted.push_back(key); - } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { - vector hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23); - CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, j, 1); - CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n); - mapAddress.insert(make_pair(key, delta)); - inserted.push_back(key); - } - } - - for (unsigned int k = 0; k < tx.vout.size(); k++) { - const CTxOut &out = tx.vout[k]; - if (out.scriptPubKey.IsPayToScriptHash()) { - vector hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22); - CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, k, 0); - mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue))); - inserted.push_back(key); - } else if (out.scriptPubKey.IsPayToPublicKeyHash()) { - vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); - std::pair ret; - CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, k, 0); - mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue))); - inserted.push_back(key); - } - } - - mapAddressInserted.insert(make_pair(txhash, inserted)); -} - -bool CTxMemPool::getAddressIndex(std::vector > &addresses, - std::vector > &results) -{ - LOCK(cs); - for (std::vector >::iterator it = addresses.begin(); it != addresses.end(); it++) { - addressDeltaMap::iterator ait = mapAddress.lower_bound(CMempoolAddressDeltaKey((*it).second, (*it).first)); - while (ait != mapAddress.end() && (*ait).first.addressBytes == (*it).first && (*ait).first.type == (*it).second) { - results.push_back(*ait); - ait++; - } - } - return true; -} - -bool CTxMemPool::removeAddressIndex(const uint256 txhash) -{ - LOCK(cs); - addressDeltaMapInserted::iterator it = mapAddressInserted.find(txhash); - - if (it != mapAddressInserted.end()) { - std::vector keys = (*it).second; - for (std::vector::iterator mit = keys.begin(); mit != keys.end(); mit++) { - mapAddress.erase(*mit); - } - mapAddressInserted.erase(it); - } - - return true; -} - -void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view) -{ - LOCK(cs); - - const CTransaction& tx = entry.GetTx(); - std::vector inserted; - - uint256 txhash = tx.GetHash(); - for (unsigned int j = 0; j < tx.vin.size(); j++) { - const CTxIn input = tx.vin[j]; - const CTxOut &prevout = view.GetOutputFor(input); - uint160 addressHash; - int addressType; - - if (prevout.scriptPubKey.IsPayToScriptHash()) { - addressHash = uint160(vector (prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22)); - addressType = 2; - } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { - addressHash = uint160(vector (prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23)); - addressType = 1; - } else { - addressHash.SetNull(); - addressType = 0; - } - - CSpentIndexKey key = CSpentIndexKey(input.prevout.hash, input.prevout.n); - CSpentIndexValue value = CSpentIndexValue(txhash, j, -1, prevout.nValue, addressType, addressHash); - - mapSpent.insert(make_pair(key, value)); - inserted.push_back(key); - - } - - mapSpentInserted.insert(make_pair(txhash, inserted)); -} - -bool CTxMemPool::getSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) -{ - LOCK(cs); - mapSpentIndex::iterator it; - - it = mapSpent.find(key); - if (it != mapSpent.end()) { - value = it->second; - return true; - } - return false; -} - -bool CTxMemPool::removeSpentIndex(const uint256 txhash) -{ - LOCK(cs); - mapSpentIndexInserted::iterator it = mapSpentInserted.find(txhash); - - if (it != mapSpentInserted.end()) { - std::vector keys = (*it).second; - for (std::vector::iterator mit = keys.begin(); mit != keys.end(); mit++) { - mapSpent.erase(*mit); - } - mapSpentInserted.erase(it); - } - - return true; -} - void CTxMemPool::removeUnchecked(txiter it) { const uint256 hash = it->GetTx().GetHash(); @@ -593,8 +454,6 @@ void CTxMemPool::removeUnchecked(txiter it) mapTx.erase(it); nTransactionsUpdated++; minerPolicyEstimator->removeTx(hash); - removeAddressIndex(hash); - removeSpentIndex(hash); } // Calculates descendants of entry that are not already in setDescendants, and adds to diff --git a/src/txmempool.h b/src/txmempool.h index 840154f9d..e3d9d5619 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -9,8 +9,6 @@ #include #include -#include "addressindex.h" -#include "spentindex.h" #include "amount.h" #include "coins.h" #include "primitives/transaction.h" @@ -476,18 +474,6 @@ private: typedef std::map txlinksMap; txlinksMap mapLinks; - typedef std::map addressDeltaMap; - addressDeltaMap mapAddress; - - typedef std::map > addressDeltaMapInserted; - addressDeltaMapInserted mapAddressInserted; - - typedef std::map mapSpentIndex; - mapSpentIndex mapSpent; - - typedef std::map > mapSpentIndexInserted; - mapSpentIndexInserted mapSpentInserted; - void UpdateParent(txiter entry, txiter parent, bool add); void UpdateChild(txiter entry, txiter child, bool add); @@ -519,15 +505,6 @@ public: bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true); bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate = true); - void addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view); - bool getAddressIndex(std::vector > &addresses, - std::vector > &results); - bool removeAddressIndex(const uint256 txhash); - - void addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view); - bool getSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value); - bool removeSpentIndex(const uint256 txhash); - void removeRecursive(const CTransaction &tx, std::list& removed); void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); void removeConflicts(const CTransaction &tx, std::list& removed); diff --git a/src/wallet-utility.cpp b/src/wallet-utility.cpp deleted file mode 100644 index 11a56a65c..000000000 --- a/src/wallet-utility.cpp +++ /dev/null @@ -1,340 +0,0 @@ -#include -#include - -// Include local headers -#include "wallet/walletdb.h" -#include "util.h" -#include "base58.h" -#include "dstencode.h" -#include "wallet/crypter.h" -#include - - -void show_help() -{ - std::cout << - "This program outputs Bitcoin addresses and private keys from a wallet.dat file" << std::endl - << std::endl - << "Usage and options: " - << std::endl - << " -datadir= to tell the program where your wallet is" - << std::endl - << " -wallet= (Optional) if your wallet is not named wallet.dat" - << std::endl - << " -regtest or -testnet (Optional) dumps addresses from regtest/testnet" - << std::endl - << " -dumppass (Optional)if you want to extract private keys associated with addresses" - << std::endl - << " -pass= if you have encrypted private keys stored in your wallet" - << std::endl; -} - - -class WalletUtilityDB : public CDB -{ - private: - typedef std::map MasterKeyMap; - MasterKeyMap mapMasterKeys; - unsigned int nMasterKeyMaxID; - SecureString mPass; - std::vector vMKeys; - - public: - WalletUtilityDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnClose = true) : CDB(strFilename, pszMode, fFlushOnClose) - { - nMasterKeyMaxID = 0; - mPass.reserve(100); - } - - std::string getAddress(CDataStream ssKey); - std::string getKey(CDataStream ssKey, CDataStream ssValue); - std::string getCryptedKey(CDataStream ssKey, CDataStream ssValue, std::string masterPass); - bool updateMasterKeys(CDataStream ssKey, CDataStream ssValue); - bool parseKeys(bool dumppriv, std::string masterPass); - - bool DecryptSecret(const std::vector& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext); - bool Unlock(); - bool DecryptKey(const std::vector& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key); -}; - - -/* - * Address from a public key in base58 - */ -std::string WalletUtilityDB::getAddress(CDataStream ssKey) -{ - CPubKey vchPubKey; - ssKey >> vchPubKey; - CKeyID id = vchPubKey.GetID(); - std::string strAddr = EncodeDestination(id); - - return strAddr; -} - - -/* - * Non encrypted private key in WIF - */ -std::string WalletUtilityDB::getKey(CDataStream ssKey, CDataStream ssValue) -{ - std::string strKey; - CPubKey vchPubKey; - ssKey >> vchPubKey; - CPrivKey pkey; - CKey key; - - ssValue >> pkey; - if (key.Load(pkey, vchPubKey, true)) - strKey = CBitcoinSecret(key).ToString(); - - return strKey; -} - - -bool WalletUtilityDB::DecryptSecret(const std::vector& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext) -{ - CCrypter cKeyCrypter; - std::vector chIV(WALLET_CRYPTO_KEY_SIZE); - memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); - - BOOST_FOREACH(const CKeyingMaterial vMKey, vMKeys) - { - if(!cKeyCrypter.SetKey(vMKey, chIV)) - continue; - if (cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext))) - return true; - } - return false; -} - - -bool WalletUtilityDB::Unlock() -{ - CCrypter crypter; - CKeyingMaterial vMasterKey; - - BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys) - { - if(!crypter.SetKeyFromPassphrase(mPass, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) - return false; - if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) - continue; // try another master key - vMKeys.push_back(vMasterKey); - } - return true; -} - - -bool WalletUtilityDB::DecryptKey(const std::vector& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key) -{ - CKeyingMaterial vchSecret; - if(!DecryptSecret(vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) - return false; - - if (vchSecret.size() != 32) - return false; - - key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed()); - return true; -} - - -/* - * Encrypted private key in WIF format - */ -std::string WalletUtilityDB::getCryptedKey(CDataStream ssKey, CDataStream ssValue, std::string masterPass) -{ - mPass = masterPass.c_str(); - CPubKey vchPubKey; - ssKey >> vchPubKey; - CKey key; - - std::vector vKey; - ssValue >> vKey; - - if (!Unlock()) - return ""; - - if(!DecryptKey(vKey, vchPubKey, key)) - return ""; - - std::string strKey = CBitcoinSecret(key).ToString(); - return strKey; -} - - -/* - * Master key derivation - */ -bool WalletUtilityDB::updateMasterKeys(CDataStream ssKey, CDataStream ssValue) -{ - unsigned int nID; - ssKey >> nID; - CMasterKey kMasterKey; - ssValue >> kMasterKey; - if (mapMasterKeys.count(nID) != 0) - { - std::cout << "Error reading wallet database: duplicate CMasterKey id " << nID << std::endl; - return false; - } - mapMasterKeys[nID] = kMasterKey; - - if (nMasterKeyMaxID < nID) - nMasterKeyMaxID = nID; - - return true; -} - - -/* - * Look at all the records and parse keys for addresses and private keys - */ -bool WalletUtilityDB::parseKeys(bool dumppriv, std::string masterPass) -{ - DBErrors result = DB_LOAD_OK; - std::string strType; - bool first = true; - - try { - Dbc* pcursor = GetCursor(); - if (!pcursor) - { - LogPrintf("Error getting wallet database cursor\n"); - result = DB_CORRUPT; - } - - if (dumppriv) - { - while (result == DB_LOAD_OK && true) - { - CDataStream ssKey(SER_DISK, CLIENT_VERSION); - CDataStream ssValue(SER_DISK, CLIENT_VERSION); - int result = ReadAtCursor(pcursor, ssKey, ssValue); - - if (result == DB_NOTFOUND) { - break; - } - else if (result != 0) - { - LogPrintf("Error reading next record from wallet database\n"); - result = DB_CORRUPT; - break; - } - - ssKey >> strType; - if (strType == "mkey") - { - updateMasterKeys(ssKey, ssValue); - } - } - pcursor->close(); - pcursor = GetCursor(); - } - - while (result == DB_LOAD_OK && true) - { - CDataStream ssKey(SER_DISK, CLIENT_VERSION); - CDataStream ssValue(SER_DISK, CLIENT_VERSION); - int ret = ReadAtCursor(pcursor, ssKey, ssValue); - - if (ret == DB_NOTFOUND) - { - std::cout << " ]" << std::endl; - first = true; - break; - } - else if (ret != DB_LOAD_OK) - { - LogPrintf("Error reading next record from wallet database\n"); - result = DB_CORRUPT; - break; - } - - ssKey >> strType; - - if (strType == "key" || strType == "ckey") - { - std::string strAddr = getAddress(ssKey); - std::string strKey = ""; - - - if (dumppriv && strType == "key") - strKey = getKey(ssKey, ssValue); - if (dumppriv && strType == "ckey") - { - if (masterPass == "") - { - std::cout << "Encrypted wallet, please provide a password. See help below" << std::endl; - show_help(); - result = DB_LOAD_FAIL; - break; - } - strKey = getCryptedKey(ssKey, ssValue, masterPass); - } - - if (strAddr != "") - { - if (first) - std::cout << "[ "; - else - std::cout << ", "; - } - - if (dumppriv) - { - std::cout << "{\"addr\" : \"" + strAddr + "\", " - << "\"pkey\" : \"" + strKey + "\"}" - << std::flush; - } - else - { - std::cout << "\"" + strAddr + "\""; - } - - first = false; - } - } - - pcursor->close(); - } catch (DbException &e) { - std::cout << "DBException caught " << e.get_errno() << std::endl; - } catch (std::exception &e) { - std::cout << "Exception caught " << std::endl; - } - - if (result == DB_LOAD_OK) - return true; - else - return false; -} - - -int main(int argc, char* argv[]) -{ - ParseParameters(argc, argv); - std::string walletFile = GetArg("-wallet", "wallet.dat"); - std::string masterPass = GetArg("-pass", ""); - bool fDumpPass = GetBoolArg("-dumppass", false); - bool help = GetBoolArg("-h", false); - bool result = false; - - if (help) - { - show_help(); - return 0; - } - - try { - SelectParams(ChainNameFromCommandLine()); - result = WalletUtilityDB(walletFile, "r").parseKeys(fDumpPass, masterPass); - } - catch (const std::exception& e) { - std::cout << "Error opening wallet file " << walletFile << std::endl; - std::cout << e.what() << std::endl; - } - - if (result) - return 0; - else - return -1; -}