Browse Source

Make listsinceblock refuse unknown block hash

Change suggested by Cory Fields <cory-nospam-@coryfields.com> who noticed
listsinceblock would ignore invalid block hashes causing it to return a
completely unfiltered list of transactions.

Github-Pull: #11565
Rebased-From: 659b2061c4
Tree-SHA512: 2091a830b730421b49c806cb83a16c7da2ec0a7adac2bac0585324aad12a32bb99a840264c3d346937ea84786fac56e44befb6641511a417977803875efe5a21
tags/v0.15.1
Russell Yanofsky 3 years ago
parent
commit
7d4546f17d
No account linked to committer's email address
3 changed files with 48 additions and 10 deletions
  1. 4
    0
      doc/release-notes.md
  2. 10
    9
      src/wallet/rpcwallet.cpp
  3. 34
    1
      test/functional/listsinceblock.py

+ 4
- 0
doc/release-notes.md View File

@@ -68,6 +68,10 @@ Notable changes
- `dumpwallet` no longer allows overwriting files. This is a security measure
as well as prevents dangerous user mistakes.

- `listsinceblock` will now throw an error if an unknown `blockhash` argument
value is passed, instead of returning a list of all wallet transactions since
the genesis block.

Credits
=======


+ 10
- 9
src/wallet/rpcwallet.cpp View File

@@ -1823,19 +1823,20 @@ UniValue listsinceblock(const JSONRPCRequest& request)
int target_confirms = 1;
isminefilter filter = ISMINE_SPENDABLE;

if (!request.params[0].isNull()) {
if (!request.params[0].isNull() && !request.params[0].get_str().empty()) {
uint256 blockId;

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


+ 34
- 1
test/functional/listsinceblock.py View File

@@ -5,7 +5,7 @@
"""Test the listsincelast RPC."""

from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
from test_framework.util import assert_equal, assert_array_result, assert_raises_rpc_error

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

self.test_no_blockhash()
self.test_invalid_blockhash()
self.test_reorg()
self.test_double_spend()
self.test_double_send()

def test_no_blockhash(self):
txid = self.nodes[2].sendtoaddress(self.nodes[0].getnewaddress(), 1)
blockhash, = self.nodes[2].generate(1)
self.sync_all()

txs = self.nodes[0].listtransactions()
assert_array_result(txs, {"txid": txid}, {
"category": "receive",
"amount": 1,
"blockhash": blockhash,
"confirmations": 1,
})
assert_equal(
self.nodes[0].listsinceblock(),
{"lastblock": blockhash,
"removed": [],
"transactions": txs})
assert_equal(
self.nodes[0].listsinceblock(""),
{"lastblock": blockhash,
"removed": [],
"transactions": txs})

def test_invalid_blockhash(self):
assert_raises_rpc_error(-5, "Block not found", self.nodes[0].listsinceblock,
"42759cde25462784395a337460bde75f58e73d3f08bd31fdc3507cbac856a2c4")
assert_raises_rpc_error(-5, "Block not found", self.nodes[0].listsinceblock,
"0000000000000000000000000000000000000000000000000000000000000000")
assert_raises_rpc_error(-5, "Block not found", self.nodes[0].listsinceblock,
"invalid-hex")

def test_reorg(self):
'''
`listsinceblock` did not behave correctly when handed a block that was

Loading…
Cancel
Save