Skip to content

Commit e1f6a2a

Browse files
committed
Merge #11565: Make listsinceblock refuse unknown block hash
659b206 Make listsinceblock refuse unknown block hash (Russell Yanofsky) Pull request description: Change suggested by @theuni who noticed listsinceblock would ignore invalid block hashes causing it to return a completely unfiltered list of transactions. Tree-SHA512: 3c8fb160265780d1334e856e853ab48e2e18372b8f1fc71ae480c3f45317048cc1fee0055d5c58031981a91b9c2bdbeb8e49a889d04ecba61729ce8109f2ce3f
2 parents 2631d55 + 659b206 commit e1f6a2a

File tree

3 files changed

+47
-10
lines changed

3 files changed

+47
-10
lines changed

doc/release-notes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ will only create hierarchical deterministic (HD) wallets.
7676

7777
Low-level RPC changes
7878
----------------------
79+
- `listsinceblock` will now throw an error if an unknown `blockhash` argument
80+
value is passed, instead of returning a list of all wallet transactions since
81+
the genesis block.
7982
- The "currentblocksize" value in getmininginfo has been removed.
8083
- The deprecated RPC `getinfo` was removed. It is recommended that the more specific RPCs are used:
8184
* `getblockchaininfo`

src/wallet/rpcwallet.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,19 +1893,20 @@ UniValue listsinceblock(const JSONRPCRequest& request)
18931893
int target_confirms = 1;
18941894
isminefilter filter = ISMINE_SPENDABLE;
18951895

1896-
if (!request.params[0].isNull()) {
1896+
if (!request.params[0].isNull() && !request.params[0].get_str().empty()) {
18971897
uint256 blockId;
18981898

18991899
blockId.SetHex(request.params[0].get_str());
19001900
BlockMap::iterator it = mapBlockIndex.find(blockId);
1901-
if (it != mapBlockIndex.end()) {
1902-
paltindex = pindex = it->second;
1903-
if (chainActive[pindex->nHeight] != pindex) {
1904-
// the block being asked for is a part of a deactivated chain;
1905-
// we don't want to depend on its perceived height in the block
1906-
// chain, we want to instead use the last common ancestor
1907-
pindex = chainActive.FindFork(pindex);
1908-
}
1901+
if (it == mapBlockIndex.end()) {
1902+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1903+
}
1904+
paltindex = pindex = it->second;
1905+
if (chainActive[pindex->nHeight] != pindex) {
1906+
// the block being asked for is a part of a deactivated chain;
1907+
// we don't want to depend on its perceived height in the block
1908+
// chain, we want to instead use the last common ancestor
1909+
pindex = chainActive.FindFork(pindex);
19091910
}
19101911
}
19111912

test/functional/listsinceblock.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""Test the listsincelast RPC."""
66

77
from test_framework.test_framework import BitcoinTestFramework
8-
from test_framework.util import assert_equal
8+
from test_framework.util import assert_equal, assert_array_result, assert_raises_rpc_error
99

1010
class ListSinceBlockTest (BitcoinTestFramework):
1111
def set_test_params(self):
@@ -16,10 +16,43 @@ def run_test(self):
1616
self.nodes[2].generate(101)
1717
self.sync_all()
1818

19+
self.test_no_blockhash()
20+
self.test_invalid_blockhash()
1921
self.test_reorg()
2022
self.test_double_spend()
2123
self.test_double_send()
2224

25+
def test_no_blockhash(self):
26+
txid = self.nodes[2].sendtoaddress(self.nodes[0].getnewaddress(), 1)
27+
blockhash, = self.nodes[2].generate(1)
28+
self.sync_all()
29+
30+
txs = self.nodes[0].listtransactions()
31+
assert_array_result(txs, {"txid": txid}, {
32+
"category": "receive",
33+
"amount": 1,
34+
"blockhash": blockhash,
35+
"confirmations": 1,
36+
})
37+
assert_equal(
38+
self.nodes[0].listsinceblock(),
39+
{"lastblock": blockhash,
40+
"removed": [],
41+
"transactions": txs})
42+
assert_equal(
43+
self.nodes[0].listsinceblock(""),
44+
{"lastblock": blockhash,
45+
"removed": [],
46+
"transactions": txs})
47+
48+
def test_invalid_blockhash(self):
49+
assert_raises_rpc_error(-5, "Block not found", self.nodes[0].listsinceblock,
50+
"42759cde25462784395a337460bde75f58e73d3f08bd31fdc3507cbac856a2c4")
51+
assert_raises_rpc_error(-5, "Block not found", self.nodes[0].listsinceblock,
52+
"0000000000000000000000000000000000000000000000000000000000000000")
53+
assert_raises_rpc_error(-5, "Block not found", self.nodes[0].listsinceblock,
54+
"invalid-hex")
55+
2356
def test_reorg(self):
2457
'''
2558
`listsinceblock` did not behave correctly when handed a block that was

0 commit comments

Comments
 (0)