1919
2020from _decimal import Decimal
2121from random import randint
22- from typing import Optional
22+ from typing import List , Optional
2323
2424# See CMainParams in src/chainparams.cpp
2525DEFAULT_PORT_MAINNET_CORE_P2P = 9999
2929# See CDeterministicMNStateDiff::ToJson() in src/evo/dmnstate.h
3030DMNSTATE_DIFF_DUMMY_ADDR = "255.255.255.255"
3131
32- class Node :
32+ class EvoNode :
3333 mn : MasternodeInfo
3434 node : TestNode
3535 platform_nodeid : str = ""
3636
37- def __init__ (self , node : TestNode , is_evo : bool ):
38- self .mn = MasternodeInfo (evo = is_evo , legacy = False )
37+ def __init__ (self , node : TestNode ):
38+ self .mn = MasternodeInfo (evo = True , legacy = False )
3939 self .mn .generate_addresses (node )
4040 self .mn .set_node (node .index )
4141 self .mn .set_params (nodePort = p2p_port (node .index ))
4242 self .node = node
4343
4444 def generate_collateral (self , test : BitcoinTestFramework ):
4545 assert self .mn .nodeIdx is not None
46-
46+ # Generate enough blocks to cover collateral amount
4747 while self .node .getbalance () < self .mn .get_collateral_value ():
4848 test .bump_mocktime (1 )
4949 test .generate (self .node , 10 , sync_fun = test .no_op )
50-
50+ # Create collateral UTXO
5151 collateral_txid = self .node .sendmany ("" , {self .mn .collateral_address : self .mn .get_collateral_value (), self .mn .fundsAddr : 1 })
5252 self .mn .bury_tx (test , self .mn .nodeIdx , collateral_txid , 1 )
5353 collateral_vout = self .mn .get_collateral_vout (self .node , collateral_txid )
@@ -60,68 +60,51 @@ def is_mn_visible(self, _protx_hash = None) -> bool:
6060 for mn_entry in mn_list :
6161 dmn = mn_list .get (mn_entry )
6262 if dmn ['proTxHash' ] == protx_hash :
63- assert_equal (dmn ['type' ], "Evo" if self . mn . evo else "Regular" )
63+ assert_equal (dmn ['type' ], "Evo" )
6464 mn_visible = True
6565 return mn_visible
6666
67- def register_mn (self , test : BitcoinTestFramework , submit : bool , addrs_core_p2p , addrs_platform_p2p = None , addrs_platform_https = None , code = None , msg = None ) -> str :
68- assert self .mn .nodeIdx is not None
67+ def set_active_state (self , test : BitcoinTestFramework , active : bool , more_extra_args : Optional [List [str ]] = None ):
68+ assert self .mn .proTxHash and self .mn .keyOperator
69+ target_extra_args = self .node .extra_args .copy ()
70+ if active :
71+ target_extra_args += [f'-masternodeblsprivkey={ self .mn .keyOperator } ' ]
72+ if more_extra_args is not None :
73+ target_extra_args += more_extra_args
74+ test .restart_node (self .mn .nodeIdx , extra_args = target_extra_args )
6975
70- if self .mn .evo and (not addrs_platform_https or not addrs_platform_p2p ):
71- raise AssertionError ("EvoNode but addrs_platform_p2p and addrs_platform_https not specified" )
72-
73- # Evonode-specific fields are ignored if regular masternode
76+ def register_mn (self , test : BitcoinTestFramework , submit : bool , addrs_core_p2p , addrs_platform_p2p , addrs_platform_https , code = None , msg = None ) -> Optional [str ]:
77+ assert self .mn .nodeIdx is not None
7478 self .platform_nodeid = hash160 (b'%d' % randint (1 , 65535 )).hex ()
7579 protx_output = self .mn .register (self .node , submit = submit , addrs_core_p2p = addrs_core_p2p , operator_reward = 0 ,
7680 platform_node_id = self .platform_nodeid , addrs_platform_p2p = addrs_platform_p2p ,
7781 addrs_platform_https = addrs_platform_https , expected_assert_code = code , expected_assert_msg = msg )
78-
79- # If we expected error, make sure the transaction didn't succeed
80- if code and msg :
81- assert protx_output is None
82- return ""
83- else :
84- assert protx_output is not None
85- if not submit :
86- return ""
87-
82+ if (code and msg ) or not submit :
83+ return protx_output
84+ assert protx_output is not None
8885 # Bury ProTx transaction and check if masternode is online
8986 self .mn .set_params (proTxHash = protx_output , operator_reward = 0 )
9087 self .mn .bury_tx (test , self .mn .nodeIdx , protx_output , 1 )
9188 assert_equal (self .is_mn_visible (), True )
92-
93- test .log .debug (f"Registered { 'Evo' if self .mn .evo else 'regular' } masternode with collateral_txid={ self .mn .collateral_txid } , "
94- f"collateral_vout={ self .mn .collateral_vout } , provider_txid={ self .mn .proTxHash } " )
95-
96- test .restart_node (self .mn .nodeIdx , extra_args = self .node .extra_args + [f'-masternodeblsprivkey={ self .mn .keyOperator } ' ])
89+ test .log .debug (f"Registered EvoNode with collateral_txid={ self .mn .collateral_txid } , collateral_vout={ self .mn .collateral_vout } , provider_txid={ self .mn .proTxHash } " )
9790 return self .mn .proTxHash
9891
99- def update_mn (self , test : BitcoinTestFramework , addrs_core_p2p , addrs_platform_p2p = None , addrs_platform_https = None ) -> str :
92+ def update_mn (self , test : BitcoinTestFramework , addrs_core_p2p , addrs_platform_p2p , addrs_platform_https ) -> str :
10093 assert self .mn .nodeIdx is not None
101-
102- if self .mn .evo and (not addrs_platform_https or not addrs_platform_p2p ):
103- raise AssertionError ("EvoNode but addrs_platform_p2p and addrs_platform_https not specified" )
104-
105- # Evonode-specific fields are ignored if regular masternode
10694 protx_output = self .mn .update_service (self .node , submit = True , addrs_core_p2p = addrs_core_p2p , platform_node_id = self .platform_nodeid ,
10795 addrs_platform_p2p = addrs_platform_p2p , addrs_platform_https = addrs_platform_https )
10896 assert protx_output is not None
109-
11097 self .mn .bury_tx (test , self .mn .nodeIdx , protx_output , 1 )
11198 assert_equal (self .is_mn_visible (), True )
112-
113- test .log .debug (f"Updated { 'Evo' if self .mn .evo else 'regular' } masternode with collateral_txid={ self .mn .collateral_txid } , "
114- f"collateral_vout={ self .mn .collateral_vout } , provider_txid={ self .mn .proTxHash } " )
99+ test .log .debug (f"Updated EvoNode with collateral_txid={ self .mn .collateral_txid } , collateral_vout={ self .mn .collateral_vout } , provider_txid={ self .mn .proTxHash } " )
115100 return protx_output
116101
117102 def destroy_mn (self , test : BitcoinTestFramework ):
118103 assert self .mn .nodeIdx is not None
119-
120104 # Get UTXO from address used to pay fees, generate new addresses
121105 address_funds_unspent = self .node .listunspent (0 , 99999 , [self .mn .fundsAddr ])[0 ]
122106 address_funds_value = address_funds_unspent ['amount' ]
123107 self .mn .generate_addresses (self .node , True )
124-
125108 # Create transaction to spend old collateral and fee change
126109 raw_tx = self .node .createrawtransaction ([
127110 { 'txid' : self .mn .collateral_txid , 'vout' : self .mn .collateral_vout },
@@ -131,19 +114,15 @@ def destroy_mn(self, test: BitcoinTestFramework):
131114 {self .mn .fundsAddr : float (address_funds_value - Decimal (0.001 ))}
132115 ])
133116 raw_tx = self .node .signrawtransactionwithwallet (raw_tx )['hex' ]
134-
135117 # Send that transaction, resulting txid is new collateral
136118 new_collateral_txid = self .node .sendrawtransaction (raw_tx )
137119 self .mn .bury_tx (test , self .mn .nodeIdx , new_collateral_txid , 1 )
138120 new_collateral_vout = self .mn .get_collateral_vout (self .node , new_collateral_txid )
121+ old_protx_hash = self .mn .proTxHash
139122 self .mn .set_params (proTxHash = "" , collateral_txid = new_collateral_txid , collateral_vout = new_collateral_vout )
140-
141123 # Old masternode entry should be dead
142- assert_equal (self .is_mn_visible (self .mn .proTxHash ), False )
143- test .log .debug (f"Destroyed { 'Evo' if self .mn .evo else 'regular' } masternode with collateral_txid={ self .mn .collateral_txid } , "
144- f"collateral_vout={ self .mn .collateral_vout } , provider_txid={ self .mn .proTxHash } " )
145-
146- test .restart_node (self .mn .nodeIdx , extra_args = self .node .extra_args )
124+ assert_equal (self .is_mn_visible (old_protx_hash ), False )
125+ test .log .debug (f"Destroyed EvoNode with collateral_txid={ self .mn .collateral_txid } , collateral_vout={ self .mn .collateral_vout } , provider_txid={ old_protx_hash } " )
147126
148127class NetInfoTest (BitcoinTestFramework ):
149128 def set_test_params (self ):
@@ -163,8 +142,13 @@ def check_netinfo_fields(self, val, core_p2p_port: int, plat_https_port: Optiona
163142 if plat_p2p_port :
164143 assert_equal (val ['platform_p2p' ][0 ], f"127.0.0.1:{ plat_p2p_port } " )
165144
145+ def reconnect_nodes (self ):
146+ # Needed as restarts don't reconnect nodes
147+ for idx in range (1 , self .num_nodes ):
148+ self .connect_nodes (0 , idx )
149+
166150 def run_test (self ):
167- self .node_evo : Node = Node (self .nodes [0 ], True )
151+ self .node_evo : EvoNode = EvoNode (self .nodes [0 ])
168152 self .node_evo .generate_collateral (self )
169153
170154 self .node_simple : TestNode = self .nodes [1 ]
@@ -229,17 +213,17 @@ def test_deprecation(self):
229213 proregtx_rpc = self .node_evo .node .getrawtransaction (proregtx_hash , True )
230214
231215 # CDeterministicMNState::ToJson() <- CDeterministicMN::pdmnState <- masternode_status
216+ self .node_evo .set_active_state (self , True )
232217 masternode_status = self .node_evo .node .masternode ('status' )
233218
234219 # Generate deprecation-disabled response to avoid having to re-create a masternode again later on
235- self .restart_node (self .node_evo .mn .nodeIdx , extra_args = self .node_evo .node .extra_args +
236- [f'-masternodeblsprivkey={ self .node_evo .mn .keyOperator } ' , '-deprecatedrpc=service' ])
237- self .connect_nodes (self .node_evo .mn .nodeIdx , self .node_simple .index ) # Needed as restarts don't reconnect nodes
220+ self .node_evo .set_active_state (self , True , ['-deprecatedrpc=service' ])
221+ self .reconnect_nodes ()
238222 masternode_status_depr = self .node_evo .node .masternode ('status' )
239223
240224 # Stop actively running the masternode so we can issue a CProUpServTx (and enable the deprecation)
241- self .restart_node ( self . node_evo .mn . nodeIdx , extra_args = self . node_evo . node . extra_args )
242- self .connect_nodes ( self . node_evo . mn . nodeIdx , self . node_simple . index ) # Needed as restarts don't reconnect nodes
225+ self .node_evo .set_active_state ( self , False )
226+ self .reconnect_nodes ()
243227
244228 # CProUpServTx::ToJson() <- TxToUniv() <- TxToJSON() <- getrawtransaction
245229 # We need to update *thrice*, the first time to incorrect values and the second time, (back) to correct values and the third time, only
@@ -297,8 +281,9 @@ def test_deprecation(self):
297281 # relevant on the host node as opposed to expressing payload information in most other RPCs.
298282 assert "service" in masternode_status .keys ()
299283
300- self .node_evo .destroy_mn (self ) # Shut down previous masternode
301- self .connect_nodes (self .node_evo .mn .nodeIdx , self .node_simple .index ) # Needed as restarts don't reconnect nodes
284+ # Shut down masternode
285+ self .node_evo .destroy_mn (self )
286+ self .reconnect_nodes ()
302287
303288 self .log .info ("Collect RPC responses from node with -deprecatedrpc=service" )
304289
0 commit comments