Skip to content

Commit 28aaf1d

Browse files
committed
test: allow assert_raises_rpc_error with helper functions
1 parent 5aeec2a commit 28aaf1d

File tree

2 files changed

+71
-13
lines changed

2 files changed

+71
-13
lines changed

test/functional/feature_dip3_deterministicmns.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ def create_mn_collateral(self, node, mn: MasternodeInfo):
238238
def register_fund_mn(self, node, mn: MasternodeInfo):
239239
node.sendtoaddress(mn.fundsAddr, mn.get_collateral_value() + 0.001)
240240
txid = mn.register_fund(node, submit=True)
241+
assert txid is not None
241242
vout = mn.get_collateral_vout(node, txid)
242243
mn.set_params(proTxHash=txid, collateral_txid=txid, collateral_vout=vout)
243244

test/functional/test_framework/test_framework.py

Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
ser_compact_size,
3636
ser_string,
3737
tx_from_hex,
38-
39-
4038
)
4139
from .script import hash160
4240
from .p2p import NetworkThread
@@ -46,6 +44,7 @@
4644
MAX_NODES,
4745
append_config,
4846
assert_equal,
47+
assert_raises_rpc_error,
4948
check_json_precision,
5049
copy_datadir,
5150
force_finish_mnsync,
@@ -1219,7 +1218,11 @@ def get_node(self, test: BitcoinTestFramework) -> TestNode:
12191218
def register(self, node: TestNode, submit: bool, collateral_txid: Optional[str] = None, collateral_vout: Optional[int] = None,
12201219
ipAndPort: Optional[str] = None, ownerAddr: Optional[str] = None, pubKeyOperator: Optional[str] = None, votingAddr: Optional[str] = None,
12211220
operator_reward: Optional[int] = None, rewards_address: Optional[str] = None, fundsAddr: Optional[str] = None,
1222-
platform_node_id: Optional[str] = None, platform_p2p_port: Optional[int] = None, platform_http_port: Optional[int] = None) -> str:
1221+
platform_node_id: Optional[str] = None, platform_p2p_port: Optional[int] = None, platform_http_port: Optional[int] = None,
1222+
expected_assert_code: Optional[int] = None, expected_assert_msg: Optional[str] = None) -> Optional[str]:
1223+
if (expected_assert_code and not expected_assert_msg) or (not expected_assert_code and expected_assert_msg):
1224+
raise AssertionError("Intending to use assert_raises_rpc_error() but didn't specify code and message")
1225+
12231226
# EvoNode-specific fields are ignored for regular masternodes
12241227
if self.evo:
12251228
if platform_node_id is None:
@@ -1242,8 +1245,11 @@ def register(self, node: TestNode, submit: bool, collateral_txid: Optional[str]
12421245
]
12431246
address_funds = fundsAddr or self.fundsAddr
12441247

1248+
# Use assert_raises_rpc_error if we expect to error out
1249+
use_assert: bool = bool(expected_assert_code and expected_assert_msg)
1250+
12451251
# Flip a coin and decide if we will submit the transaction directly or use sendrawtransaction
1246-
use_srt: bool = bool(random.getrandbits(1)) and submit
1252+
use_srt: bool = bool(random.getrandbits(1)) and submit and not use_assert
12471253
if use_srt:
12481254
submit = False
12491255

@@ -1255,6 +1261,10 @@ def register(self, node: TestNode, submit: bool, collateral_txid: Optional[str]
12551261
command = "register_legacy" if self.legacy else "register"
12561262
args = args + [address_funds, submit] # type: ignore
12571263

1264+
if use_assert:
1265+
assert_raises_rpc_error(expected_assert_code, expected_assert_msg, node.protx, command, *args)
1266+
return None
1267+
12581268
ret: str = node.protx(command, *args)
12591269
if use_srt:
12601270
ret = node.sendrawtransaction(ret)
@@ -1264,7 +1274,11 @@ def register(self, node: TestNode, submit: bool, collateral_txid: Optional[str]
12641274
def register_fund(self, node: TestNode, submit: bool, collateral_address: Optional[str] = None, ipAndPort: Optional[str] = None,
12651275
ownerAddr: Optional[str] = None, pubKeyOperator: Optional[str] = None, votingAddr: Optional[str] = None,
12661276
operator_reward: Optional[int] = None, rewards_address: Optional[str] = None, fundsAddr: Optional[str] = None,
1267-
platform_node_id: Optional[str] = None, platform_p2p_port: Optional[int] = None, platform_http_port: Optional[int] = None) -> str:
1277+
platform_node_id: Optional[str] = None, platform_p2p_port: Optional[int] = None, platform_http_port: Optional[int] = None,
1278+
expected_assert_code: Optional[int] = None, expected_assert_msg: Optional[str] = None) -> Optional[str]:
1279+
if (expected_assert_code and not expected_assert_msg) or (not expected_assert_code and expected_assert_msg):
1280+
raise AssertionError("Intending to use assert_raises_rpc_error() but didn't specify code and message")
1281+
12681282
# EvoNode-specific fields are ignored for regular masternodes
12691283
if self.evo:
12701284
if platform_node_id is None:
@@ -1274,8 +1288,11 @@ def register_fund(self, node: TestNode, submit: bool, collateral_address: Option
12741288
if platform_http_port is None:
12751289
raise AssertionError("EvoNode but platform_http_port is missing, must be specified!")
12761290

1291+
# Use assert_raises_rpc_error if we expect to error out
1292+
use_assert: bool = bool(expected_assert_code and expected_assert_msg)
1293+
12771294
# Flip a coin and decide if we will submit the transaction directly or use sendrawtransaction
1278-
use_srt: bool = bool(random.getrandbits(1)) and submit
1295+
use_srt: bool = bool(random.getrandbits(1)) and submit and not use_assert
12791296
if use_srt:
12801297
submit = False
12811298

@@ -1299,24 +1316,36 @@ def register_fund(self, node: TestNode, submit: bool, collateral_address: Option
12991316
command = "register_fund_legacy" if self.legacy else "register_fund"
13001317
args = args + [address_funds, submit] # type: ignore
13011318

1319+
if use_assert:
1320+
assert_raises_rpc_error(expected_assert_code, expected_assert_msg, node.protx, command, *args)
1321+
return None
1322+
13021323
ret: str = node.protx(command, *args)
13031324
if use_srt:
13041325
ret = node.sendrawtransaction(ret)
13051326

13061327
return ret
13071328

1308-
def revoke(self, node: TestNode, submit: bool, reason: int, fundsAddr: Optional[str] = None) -> str:
1329+
def revoke(self, node: TestNode, submit: bool, reason: int, fundsAddr: Optional[str] = None,
1330+
expected_assert_code: Optional[int] = None, expected_assert_msg: Optional[str] = None) -> Optional[str]:
1331+
if (expected_assert_code and not expected_assert_msg) or (not expected_assert_code and expected_assert_msg):
1332+
raise AssertionError("Intending to use assert_raises_rpc_error() but didn't specify code and message")
1333+
13091334
# Update commands should be run from the appropriate MasternodeInfo instance, we do not allow overriding some values for this reason
13101335
if self.proTxHash is None:
13111336
raise AssertionError("proTxHash not set, did you call set_params()")
13121337
if self.keyOperator is None:
13131338
raise AssertionError("keyOperator not set, did you call generate_addresses()")
13141339

1340+
# Use assert_raises_rpc_error if we expect to error out
1341+
use_assert: bool = bool(expected_assert_code and expected_assert_msg)
1342+
13151343
# Flip a coin and decide if we will submit the transaction directly or use sendrawtransaction
1316-
use_srt: bool = bool(random.getrandbits(1)) and submit and (fundsAddr is not None)
1344+
use_srt: bool = bool(random.getrandbits(1)) and submit and (fundsAddr is not None) and not use_assert
13171345
if use_srt:
13181346
submit = False
13191347

1348+
command = 'revoke'
13201349
args = [
13211350
self.proTxHash,
13221351
self.keyOperator,
@@ -1329,20 +1358,31 @@ def revoke(self, node: TestNode, submit: bool, reason: int, fundsAddr: Optional[
13291358
elif submit is not True:
13301359
raise AssertionError("Cannot withhold transaction if relying on fundsAddr fallback behavior")
13311360

1332-
ret: str = node.protx('revoke', *args)
1361+
if use_assert:
1362+
assert_raises_rpc_error(expected_assert_code, expected_assert_msg, node.protx, command, *args)
1363+
return None
1364+
1365+
ret: str = node.protx(command, *args)
13331366
if use_srt:
13341367
ret = node.sendrawtransaction(ret)
13351368

13361369
return ret
13371370

13381371
def update_registrar(self, node: TestNode, submit: bool, pubKeyOperator: Optional[str] = None, votingAddr: Optional[str] = None,
1339-
rewards_address: Optional[str] = None, fundsAddr: Optional[str] = None) -> str:
1372+
rewards_address: Optional[str] = None, fundsAddr: Optional[str] = None,
1373+
expected_assert_code: Optional[int] = None, expected_assert_msg: Optional[str] = None) -> Optional[str]:
1374+
if (expected_assert_code and not expected_assert_msg) or (not expected_assert_code and expected_assert_msg):
1375+
raise AssertionError("Intending to use assert_raises_rpc_error() but didn't specify code and message")
1376+
13401377
# Update commands should be run from the appropriate MasternodeInfo instance, we do not allow overriding proTxHash for this reason
13411378
if self.proTxHash is None:
13421379
raise AssertionError("proTxHash not set, did you call set_params()")
13431380

1381+
# Use assert_raises_rpc_error if we expect to error out
1382+
use_assert: bool = bool(expected_assert_code and expected_assert_msg)
1383+
13441384
# Flip a coin and decide if we will submit the transaction directly or use sendrawtransaction
1345-
use_srt: bool = bool(random.getrandbits(1)) and submit and (fundsAddr is not None)
1385+
use_srt: bool = bool(random.getrandbits(1)) and submit and (fundsAddr is not None) and not use_assert
13461386
if use_srt:
13471387
submit = False
13481388

@@ -1360,14 +1400,22 @@ def update_registrar(self, node: TestNode, submit: bool, pubKeyOperator: Optiona
13601400
elif submit is not True:
13611401
raise AssertionError("Cannot withhold transaction if relying on fundsAddr fallback behavior")
13621402

1403+
if use_assert:
1404+
assert_raises_rpc_error(expected_assert_code, expected_assert_msg, node.protx, command, *args)
1405+
return None
1406+
13631407
ret: str = node.protx(command, *args)
13641408
if use_srt:
13651409
ret = node.sendrawtransaction(ret)
13661410

13671411
return ret
13681412

13691413
def update_service(self, node: TestNode, submit: bool, ipAndPort: Optional[str] = None, platform_node_id: Optional[str] = None, platform_p2p_port: Optional[int] = None,
1370-
platform_http_port: Optional[int] = None, address_operator: Optional[str] = None, fundsAddr: Optional[str] = None) -> str:
1414+
platform_http_port: Optional[int] = None, address_operator: Optional[str] = None, fundsAddr: Optional[str] = None,
1415+
expected_assert_code: Optional[int] = None, expected_assert_msg: Optional[str] = None) -> Optional[str]:
1416+
if (expected_assert_code and not expected_assert_msg) or (not expected_assert_code and expected_assert_msg):
1417+
raise AssertionError("Intending to use assert_raises_rpc_error() but didn't specify code and message")
1418+
13711419
# Update commands should be run from the appropriate MasternodeInfo instance, we do not allow overriding some values for this reason
13721420
if self.proTxHash is None:
13731421
raise AssertionError("proTxHash not set, did you call set_params()")
@@ -1383,8 +1431,11 @@ def update_service(self, node: TestNode, submit: bool, ipAndPort: Optional[str]
13831431
if platform_http_port is None:
13841432
raise AssertionError("EvoNode but platform_http_port is missing, must be specified!")
13851433

1434+
# Use assert_raises_rpc_error if we expect to error out
1435+
use_assert: bool = bool(expected_assert_code and expected_assert_msg)
1436+
13861437
# Flip a coin and decide if we will submit the transaction directly or use sendrawtransaction
1387-
use_srt: bool = bool(random.getrandbits(1)) and submit
1438+
use_srt: bool = bool(random.getrandbits(1)) and submit and not use_assert
13881439
if use_srt:
13891440
submit = False
13901441

@@ -1405,6 +1456,10 @@ def update_service(self, node: TestNode, submit: bool, ipAndPort: Optional[str]
14051456
command = "update_service"
14061457
args = args + [address_operator, address_funds, submit] # type: ignore
14071458

1459+
if use_assert:
1460+
assert_raises_rpc_error(expected_assert_code, expected_assert_msg, node.protx, command, *args)
1461+
return None
1462+
14081463
ret: str = node.protx(command, *args)
14091464
if use_srt:
14101465
ret = node.sendrawtransaction(ret)
@@ -1594,6 +1649,7 @@ def dynamically_prepare_masternode(self, idx, node_p2p_port, evo=False, rnd=None
15941649
# platform_node_id, platform_p2p_port and platform_http_port are ignored for regular masternodes
15951650
protx_result = mn.register(self.nodes[0], submit=True, collateral_txid=collateral_txid, collateral_vout=collateral_vout, ipAndPort=ipAndPort, operator_reward=operatorReward,
15961651
platform_node_id=platform_node_id, platform_p2p_port=platform_p2p_port, platform_http_port=platform_http_port)
1652+
assert protx_result is not None
15971653

15981654
self.bump_mocktime(10 * 60 + 1) # to make tx safe to include in block
15991655
mn.bury_tx(self, genIdx=0, txid=protx_result, depth=1)
@@ -1622,6 +1678,7 @@ def dynamically_evo_update_service(self, evo_info: MasternodeInfo, rnd=None, sho
16221678
protx_success = False
16231679
try:
16241680
protx_result = evo_info.update_service(self.nodes[0], True, f'127.0.0.1:{evo_info.nodePort}', platform_node_id, platform_p2p_port, platform_http_port, operator_reward_address, funds_address)
1681+
assert protx_result is not None
16251682
self.bump_mocktime(10 * 60 + 1) # to make tx safe to include in block
16261683
evo_info.bury_tx(self, genIdx=0, txid=protx_result, depth=1)
16271684
self.log.info("Updated EvoNode %s: platformNodeID=%s, platformP2PPort=%s, platformHTTPPort=%s" % (evo_info.proTxHash, platform_node_id, platform_p2p_port, platform_http_port))

0 commit comments

Comments
 (0)