2020from _decimal import Decimal
2121from random import randint
2222
23+ # See CMainParams in src/chainparams.cpp
24+ DEFAULT_PORT_MAINNET_CORE_P2P = 9999
2325# See CRegTestParams in src/chainparams.cpp
2426DEFAULT_PORT_PLATFORM_P2P = 22200
2527DEFAULT_PORT_PLATFORM_HTTP = 22201
@@ -61,7 +63,7 @@ def is_mn_visible(self, _protx_hash = None) -> bool:
6163 mn_visible = True
6264 return mn_visible
6365
64- def register_mn (self , test : BitcoinTestFramework , submit : bool , addrs_core_p2p , addrs_platform_p2p = None , addrs_platform_http = None ) -> str :
66+ def register_mn (self , test : BitcoinTestFramework , submit : bool , addrs_core_p2p , addrs_platform_p2p = None , addrs_platform_http = None , code = None , msg = None ) -> str :
6567 assert self .mn .nodeIdx is not None
6668
6769 if self .mn .evo and (not addrs_platform_http or not addrs_platform_p2p ):
@@ -71,13 +73,20 @@ def register_mn(self, test: BitcoinTestFramework, submit: bool, addrs_core_p2p,
7173 self .platform_nodeid = hash160 (b'%d' % randint (1 , 65535 )).hex ()
7274 protx_output = self .mn .register (self .node , submit = submit , coreP2PAddrs = addrs_core_p2p , operator_reward = 0 ,
7375 platform_node_id = self .platform_nodeid , platform_p2p_port = addrs_platform_p2p ,
74- platform_http_port = addrs_platform_http )
75- assert protx_output is not None
76- self .mn .set_params (proTxHash = protx_output , operator_reward = 0 )
76+ platform_http_port = addrs_platform_http , expected_assert_code = code , expected_assert_msg = msg )
77+
78+ # If we expected error, make sure the transaction didn't succeed
79+ if code and msg :
80+ assert protx_output is None
81+ return ""
7782
83+ # We didn't expect error, make sure we got an output, stop here if we don't want to submit
84+ assert protx_output is not None
7885 if not submit :
7986 return ""
8087
88+ self .mn .set_params (proTxHash = protx_output , operator_reward = 0 )
89+
8190 # Bury ProTx transaction and check if masternode is online
8291 self .mn .bury_tx (test , self .mn .nodeIdx , protx_output , 1 )
8392 assert_equal (self .is_mn_visible (), True )
@@ -172,6 +181,45 @@ def run_test(self):
172181
173182 self .node_evo .generate_collateral (self )
174183
184+ self .test_validation ()
185+ self .test_deprecation ()
186+
187+ def test_validation (self ):
188+ self .log .info ("Test input validation for masternode address fields" )
189+
190+ # Using mainnet P2P port gets refused
191+ self .node_evo .register_mn (self , False , f"127.0.0.1:{ DEFAULT_PORT_MAINNET_CORE_P2P } " ,
192+ DEFAULT_PORT_PLATFORM_P2P , DEFAULT_PORT_PLATFORM_HTTP ,
193+ - 8 , f"Error setting coreP2PAddrs[0] to '127.0.0.1:{ DEFAULT_PORT_MAINNET_CORE_P2P } ' (invalid port)" )
194+
195+ # Arrays of addresses are recognized by coreP2PAddrs (but get refused for too many entries)
196+ self .node_evo .register_mn (self , False , [f"127.0.0.1:{ self .node_evo .mn .nodePort } " , f"127.0.0.2:{ self .node_evo .mn .nodePort } " ],
197+ DEFAULT_PORT_PLATFORM_P2P , DEFAULT_PORT_PLATFORM_HTTP ,
198+ - 8 , f"Error setting coreP2PAddrs[1] to '127.0.0.2:{ self .node_evo .mn .nodePort } ' (too many entries)" )
199+
200+ # platformP2PPort and platformHTTPPort doesn't accept non-numeric inputs
201+ self .node_evo .register_mn (self , False , f"127.0.0.1:{ self .node_evo .mn .nodePort } " , f"127.0.0.1:{ DEFAULT_PORT_PLATFORM_P2P } " , DEFAULT_PORT_PLATFORM_HTTP ,
202+ - 8 , f"platformP2PPort must be a 32bit integer (not '127.0.0.1:{ DEFAULT_PORT_PLATFORM_P2P } ')" )
203+ self .node_evo .register_mn (self , False , f"127.0.0.1:{ self .node_evo .mn .nodePort } " , [f"127.0.0.1:{ DEFAULT_PORT_PLATFORM_P2P } " ], DEFAULT_PORT_PLATFORM_HTTP ,
204+ - 8 , "Invalid param for platformP2PPort, must be number" )
205+ self .node_evo .register_mn (self , False , f"127.0.0.1:{ self .node_evo .mn .nodePort } " , DEFAULT_PORT_PLATFORM_P2P , f"127.0.0.1:{ DEFAULT_PORT_PLATFORM_HTTP } " ,
206+ - 8 , f"platformHTTPPort must be a 32bit integer (not '127.0.0.1:{ DEFAULT_PORT_PLATFORM_HTTP } ')" )
207+ self .node_evo .register_mn (self , False , f"127.0.0.1:{ self .node_evo .mn .nodePort } " , DEFAULT_PORT_PLATFORM_P2P , [f"127.0.0.1:{ DEFAULT_PORT_PLATFORM_HTTP } " ],
208+ - 8 , "Invalid param for platformHTTPPort, must be number" )
209+
210+ # platformP2PPort and platformHTTPPort must be within acceptable range (i.e. a valid port number)
211+ self .node_evo .register_mn (self , False , f"127.0.0.1:{ self .node_evo .mn .nodePort } " , "0" , DEFAULT_PORT_PLATFORM_HTTP ,
212+ - 8 , "platformP2PPort must be a valid port [1-65535]" )
213+ self .node_evo .register_mn (self , False , f"127.0.0.1:{ self .node_evo .mn .nodePort } " , "65536" , DEFAULT_PORT_PLATFORM_HTTP ,
214+ - 8 , "platformP2PPort must be a valid port [1-65535]" )
215+ self .node_evo .register_mn (self , False , f"127.0.0.1:{ self .node_evo .mn .nodePort } " , DEFAULT_PORT_PLATFORM_P2P , "0" ,
216+ - 8 , "platformHTTPPort must be a valid port [1-65535]" )
217+ self .node_evo .register_mn (self , False , f"127.0.0.1:{ self .node_evo .mn .nodePort } " , DEFAULT_PORT_PLATFORM_P2P , "65536" ,
218+ - 8 , "platformHTTPPort must be a valid port [1-65535]" )
219+
220+ def test_deprecation (self ):
221+ self .log .info ("Test output masternode address fields for consistency" )
222+
175223 # netInfo is represented with JSON in CProRegTx, CProUpServTx, CDeterministicMNState and CSimplifiedMNListEntry,
176224 # so we need to test calls that rely on these underlying implementations. Start by collecting RPC responses.
177225 self .log .info ("Collect JSON RPC responses from node" )
0 commit comments