Merge bitcoin/bitcoin#24223: test: use MiniWallet for interface_rest.py

438e6f4c33 test: speedup interface_rest.py by whitelisting peers (immediate tx relay) (Sebastian Falbesoner)
11b9684dfd test: use MiniWallet for rest_interface.py (Sebastian Falbesoner)

Pull request description:

  This PR enables one more of the non-wallet functional tests (interface_rest.py) to be run even with the Bitcoin Core wallet disabled by using the MiniWallet instead, as proposed in #20078.

  Note that the original test sent funds from one node to another and checked node's balances, but the state of a node's wallet is not relevant to any of the REST endpoints, i.e. the replacement is quite stright-forward. In an additional commit, the test is further sped up by using the good ol' immediate tx relay trick (parameter `-whitelist=noban@127.0.0.1`).

ACKs for top commit:
  brunoerg:
    ACK 438e6f4c33

Tree-SHA512: eac351c5fb7e043c36c193d51545f20f563be9aaa04f3429a2bfb452ae4aa72294d2552800d6cac55c9a3ec2b4f30bcda2abcd74736dec3ed75e7d83c5af437f
This commit is contained in:
MarcoFalke 2022-02-02 09:07:42 +01:00
commit a41976ab77
No known key found for this signature in database
GPG key ID: CE2B75697E69A548

View file

@ -6,21 +6,28 @@
from decimal import Decimal from decimal import Decimal
from enum import Enum from enum import Enum
import http.client
from io import BytesIO from io import BytesIO
import json import json
from struct import pack, unpack from struct import pack, unpack
import http.client
import urllib.parse import urllib.parse
from test_framework.messages import (
BLOCK_HEADER_SIZE,
COIN,
)
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import ( from test_framework.util import (
assert_equal, assert_equal,
assert_greater_than, assert_greater_than,
assert_greater_than_or_equal, assert_greater_than_or_equal,
) )
from test_framework.wallet import (
MiniWallet,
getnewdestination,
)
from test_framework.messages import BLOCK_HEADER_SIZE
INVALID_PARAM = "abc" INVALID_PARAM = "abc"
UNKNOWN_PARAM = "0000000000000000000000000000000000000000000000000000000000000000" UNKNOWN_PARAM = "0000000000000000000000000000000000000000000000000000000000000000"
@ -43,14 +50,13 @@ def filter_output_indices_by_value(vouts, value):
class RESTTest (BitcoinTestFramework): class RESTTest (BitcoinTestFramework):
def set_test_params(self): def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2 self.num_nodes = 2
self.extra_args = [["-rest", "-blockfilterindex=1"], []] self.extra_args = [["-rest", "-blockfilterindex=1"], []]
# whitelist peers to speed up tx relay / mempool sync
for args in self.extra_args:
args.append("-whitelist=noban@127.0.0.1")
self.supports_cli = False self.supports_cli = False
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
def test_rest_request(self, uri, http_method='GET', req_type=ReqType.JSON, body='', status=200, ret_type=RetType.JSON): def test_rest_request(self, uri, http_method='GET', req_type=ReqType.JSON, body='', status=200, ret_type=RetType.JSON):
rest_uri = '/rest' + uri rest_uri = '/rest' + uri
if req_type == ReqType.JSON: if req_type == ReqType.JSON:
@ -79,17 +85,11 @@ class RESTTest (BitcoinTestFramework):
def run_test(self): def run_test(self):
self.url = urllib.parse.urlparse(self.nodes[0].url) self.url = urllib.parse.urlparse(self.nodes[0].url)
self.log.info("Mine blocks and send Bitcoin to node 1") self.wallet = MiniWallet(self.nodes[0])
self.wallet.rescan_utxos()
# Random address so node1's balance doesn't increase self.log.info("Broadcast test transaction and sync nodes")
not_related_address = "2MxqoHEdNQTyYeX1mHcbrrpzgojbosTpCvJ" txid, _ = self.wallet.send_to(from_node=self.nodes[0], scriptPubKey=getnewdestination()[1], amount=int(0.1 * COIN))
self.generate(self.nodes[0], 1)
self.generatetoaddress(self.nodes[1], 100, not_related_address)
assert_equal(self.nodes[0].getbalance(), 50)
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
self.sync_all() self.sync_all()
self.log.info("Test the /tx URI") self.log.info("Test the /tx URI")
@ -115,11 +115,9 @@ class RESTTest (BitcoinTestFramework):
self.log.info("Query an unspent TXO using the /getutxos URI") self.log.info("Query an unspent TXO using the /getutxos URI")
self.generatetoaddress(self.nodes[1], 1, not_related_address) self.generate(self.wallet, 1)
bb_hash = self.nodes[0].getbestblockhash() bb_hash = self.nodes[0].getbestblockhash()
assert_equal(self.nodes[1].getbalance(), Decimal("0.1"))
# Check chainTip response # Check chainTip response
json_obj = self.test_rest_request(f"/getutxos/{spending[0]}-{spending[1]}") json_obj = self.test_rest_request(f"/getutxos/{spending[0]}-{spending[1]}")
assert_equal(json_obj['chaintipHash'], bb_hash) assert_equal(json_obj['chaintipHash'], bb_hash)
@ -161,7 +159,7 @@ class RESTTest (BitcoinTestFramework):
response_hash = output.read(32)[::-1].hex() response_hash = output.read(32)[::-1].hex()
assert_equal(bb_hash, response_hash) # check if getutxo's chaintip during calculation was fine assert_equal(bb_hash, response_hash) # check if getutxo's chaintip during calculation was fine
assert_equal(chain_height, 102) # chain height must be 102 assert_equal(chain_height, 201) # chain height must be 201 (pre-mined chain [200] + generated block [1])
self.log.info("Test the /getutxos URI with and without /checkmempool") self.log.info("Test the /getutxos URI with and without /checkmempool")
# Create a transaction, check that it's found with /checkmempool, but # Create a transaction, check that it's found with /checkmempool, but
@ -169,7 +167,7 @@ class RESTTest (BitcoinTestFramework):
# found with or without /checkmempool. # found with or without /checkmempool.
# do a tx and don't sync # do a tx and don't sync
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) txid, _ = self.wallet.send_to(from_node=self.nodes[0], scriptPubKey=getnewdestination()[1], amount=int(0.1 * COIN))
json_obj = self.test_rest_request(f"/tx/{txid}") json_obj = self.test_rest_request(f"/tx/{txid}")
# get the spent output to later check for utxo (should be spent by then) # get the spent output to later check for utxo (should be spent by then)
spent = (json_obj['vin'][0]['txid'], json_obj['vin'][0]['vout']) spent = (json_obj['vin'][0]['txid'], json_obj['vin'][0]['vout'])
@ -301,11 +299,13 @@ class RESTTest (BitcoinTestFramework):
self.log.info("Test tx inclusion in the /mempool and /block URIs") self.log.info("Test tx inclusion in the /mempool and /block URIs")
# Make 3 tx and mine them on node 1 # Make 3 chained txs and mine them on node 1
txs = [] txs = []
txs.append(self.nodes[0].sendtoaddress(not_related_address, 11)) input_txid = txid
txs.append(self.nodes[0].sendtoaddress(not_related_address, 11)) for _ in range(3):
txs.append(self.nodes[0].sendtoaddress(not_related_address, 11)) utxo_to_spend = self.wallet.get_utxo(txid=input_txid)
txs.append(self.wallet.send_self_transfer(from_node=self.nodes[0], utxo_to_spend=utxo_to_spend)['txid'])
input_txid = txs[-1]
self.sync_all() self.sync_all()
# Check that there are exactly 3 transactions in the TX memory pool before generating the block # Check that there are exactly 3 transactions in the TX memory pool before generating the block
@ -351,5 +351,6 @@ class RESTTest (BitcoinTestFramework):
json_obj = self.test_rest_request("/chaininfo") json_obj = self.test_rest_request("/chaininfo")
assert_equal(json_obj['bestblockhash'], bb_hash) assert_equal(json_obj['bestblockhash'], bb_hash)
if __name__ == '__main__': if __name__ == '__main__':
RESTTest().main() RESTTest().main()