@@ -1104,13 +1104,13 @@ def setupDMN(self,
11041104 break
11051105 assert_greater_than (collateralTxId_n , - 1 )
11061106 assert_greater_than (json_tx ["confirmations" ], 0 )
1107- proTxId = mnOwner .protx_register (collateralTxId , collateralTxId_n , ipport , ownerAdd ,
1107+ proTxId = mnOwner .protx_register (collateralTxId , collateralTxId_n , True , ipport , ownerAdd ,
11081108 bls_keypair ["public" ], votingAdd , collateralAdd )
11091109 elif strType == "external" :
11101110 self .log .info ("Setting up ProRegTx with collateral externally-signed..." )
11111111 # send the tx from the miner
11121112 payoutAdd = mnOwner .getnewaddress ("payout" )
1113- register_res = miner .protx_register_prepare (outpoint .hash , outpoint .n , ipport , ownerAdd ,
1113+ register_res = miner .protx_register_prepare (outpoint .hash , outpoint .n , True , ipport , ownerAdd ,
11141114 bls_keypair ["public" ], votingAdd , payoutAdd )
11151115 self .log .info ("ProTx prepared" )
11161116 message_to_sign = register_res ["signMessage" ]
@@ -1205,19 +1205,20 @@ def protx_register_fund(self, miner, controller, dmn, collateral_addr, op_rew=No
12051205 Create a ProReg tx, which references an 100 PIV UTXO as collateral.
12061206 The controller node owns the collateral and creates the ProReg tx.
12071207 """
1208- def protx_register (self , miner , controller , dmn , collateral_addr ):
1208+ def protx_register (self , miner , controller , dmn , collateral_addr , transparent ):
12091209 # send to the owner the exact collateral tx amount
12101210 funding_txid = miner .sendtoaddress (collateral_addr , Decimal ('100' ))
12111211 # send another output to be used for the fee of the proReg tx
1212- miner .sendtoaddress (collateral_addr , Decimal ('1' ))
1212+ feeAddr = collateral_addr if transparent else controller .getnewaddress ("feeAddr" )
1213+ miner .sendtoaddress (feeAddr , Decimal ('1' ))
12131214 # confirm and verify reception
12141215 miner .generate (1 )
12151216 self .sync_blocks ([miner , controller ])
12161217 json_tx = controller .getrawtransaction (funding_txid , True )
12171218 assert_greater_than (json_tx ["confirmations" ], 0 )
1218- # create and send the ProRegTx
1219- dmn .collateral = COutPoint (int (funding_txid , 16 ), get_collateral_vout (json_tx ))
1220- dmn .proTx = controller .protx_register (funding_txid , dmn .collateral .n , dmn .ipport , dmn .owner ,
1219+ # create and send the ProRegTx, FOR SHIELD DMNS THIS IS NOT THE COLLATERAL CONTAINED IN THE PROREGTX (which is instead the null COutPoint (0,-1))
1220+ dmn .collateral = COutPoint (int (funding_txid , 16 ), get_collateral_vout (json_tx )) if transparent else COutPoint ( int ( funding_txid , 16 ), 0 , transparent )
1221+ dmn .proTx = controller .protx_register (funding_txid , dmn .collateral .n , transparent , dmn .ipport , dmn .owner ,
12211222 dmn .operator_pk , dmn .voting , dmn .payee )
12221223
12231224 """
@@ -1236,7 +1237,7 @@ def protx_register_ext(self, miner, controller, dmn, outpoint, fSubmit):
12361237 outpoint = COutPoint (int (funding_txid , 16 ), get_collateral_vout (json_tx ))
12371238 dmn .collateral = outpoint
12381239 # Prepare the message to be signed externally by the owner of the collateral (the controller)
1239- reg_tx = miner .protx_register_prepare ("%064x" % outpoint .hash , outpoint .n , dmn .ipport , dmn .owner ,
1240+ reg_tx = miner .protx_register_prepare ("%064x" % outpoint .hash , outpoint .n , True , dmn .ipport , dmn .owner ,
12401241 dmn .operator_pk , dmn .voting , dmn .payee )
12411242 sig = controller .signmessage (reg_tx ["collateralAddress" ], reg_tx ["signMessage" ])
12421243 if fSubmit :
@@ -1257,7 +1258,7 @@ def protx_register_ext(self, miner, controller, dmn, outpoint, fSubmit):
12571258 If not provided, a new address-key pair is generated.
12581259 :return: dmn: (Masternode) the deterministic masternode object
12591260 """
1260- def register_new_dmn (self , idx , miner_idx , controller_idx , strType ,
1261+ def register_new_dmn (self , idx , miner_idx , controller_idx , strType , transparent ,
12611262 payout_addr = None , outpoint = None , op_blskeys = None ):
12621263 # Prepare remote node
12631264 assert idx != miner_idx
@@ -1267,19 +1268,21 @@ def register_new_dmn(self, idx, miner_idx, controller_idx, strType,
12671268 mn_node = self .nodes [idx ]
12681269
12691270 # Generate ip and addresses/keys
1270- collateral_addr = controller_node .getnewaddress ("mncollateral-%d" % idx )
1271+ collateral_addr = controller_node .getnewaddress ("mncollateral-%d" % idx ) if transparent else controller_node . getnewshieldaddress ( "shieldmncollateral-%d" % idx )
12711272 if payout_addr is None :
1272- payout_addr = collateral_addr
1273- dmn = create_new_dmn (idx , controller_node , payout_addr , op_blskeys )
1273+ payout_addr = collateral_addr if transparent else controller_node . getnewaddress ( "mncollateral-%d" % idx )
1274+ dmn = create_new_dmn (idx , controller_node , payout_addr , op_blskeys , transparent )
12741275
12751276 # Create ProRegTx
12761277 self .log .info ("Creating%s proRegTx for deterministic masternode idx=%d..." % (
12771278 " and funding" if strType == "fund" else "" , idx ))
12781279 if strType == "fund" :
1280+ assert (transparent )
12791281 self .protx_register_fund (miner_node , controller_node , dmn , collateral_addr )
12801282 elif strType == "internal" :
1281- self .protx_register (miner_node , controller_node , dmn , collateral_addr )
1283+ self .protx_register (miner_node , controller_node , dmn , collateral_addr , transparent )
12821284 elif strType == "external" :
1285+ assert (transparent )
12831286 self .protx_register_ext (miner_node , controller_node , dmn , outpoint , True )
12841287 else :
12851288 raise Exception ("Type %s not available" % strType )
@@ -1294,7 +1297,7 @@ def register_new_dmn(self, idx, miner_idx, controller_idx, strType,
12941297 assert dmn .proTx in mn_node .protx_list (False )
12951298
12961299 # check coin locking
1297- assert is_coin_locked_by (controller_node , dmn .collateral )
1300+ assert is_coin_locked_by (controller_node , dmn .collateral , dmn . transparent )
12981301
12991302 # check json payload against local dmn object
13001303 self .check_proreg_payload (dmn , json_tx )
@@ -1324,23 +1327,38 @@ def check_mn_list_on_node(self, idx, mns):
13241327 assert_equal (mn .voting , mn2 ["dmnstate" ]["votingAddress" ])
13251328 assert_equal (mn .ipport , mn2 ["dmnstate" ]["service" ])
13261329 assert_equal (mn .payee , mn2 ["dmnstate" ]["payoutAddress" ])
1327- assert_equal (collateral ["txid" ], mn2 ["collateralHash" ])
1328- assert_equal (collateral ["vout" ], mn2 ["collateralIndex" ])
1330+ assert_equal (mn .nullifier , mn2 ["nullifier" ])
1331+ # Usual story, For shield Dmns the value we store in collateral (i.e. the sapling outpoint referring to the note)
1332+ # Is different from the default null collateral in the ProRegTx
1333+ if mn .transparent :
1334+ assert_equal (collateral ["txid" ], mn2 ["collateralHash" ])
1335+ assert_equal (collateral ["vout" ], mn2 ["collateralIndex" ])
1336+ else :
1337+ assert_equal ("%064x" % 0 , mn2 ["collateralHash" ])
1338+ assert_equal (- 1 , mn2 ["collateralIndex" ])
13291339
13301340 def check_proreg_payload (self , dmn , json_tx ):
13311341 assert "payload" in json_tx
13321342 # null hash if funding collateral
13331343 collateral_hash = 0 if int (json_tx ["txid" ], 16 ) == dmn .collateral .hash \
13341344 else dmn .collateral .hash
1345+ collateral_n = dmn .collateral .n
1346+ # null Outpoint if dmn is shielded
1347+ if not dmn .transparent :
1348+ collateral_hash = 0
1349+ collateral_n = - 1
13351350 pl = json_tx ["payload" ]
1336- assert_equal (pl ["version" ], 1 )
1351+ assert_equal (pl ["version" ], 2 )
13371352 assert_equal (pl ["collateralHash" ], "%064x" % collateral_hash )
1338- assert_equal (pl ["collateralIndex" ], dmn . collateral . n )
1353+ assert_equal (pl ["collateralIndex" ], collateral_n )
13391354 assert_equal (pl ["service" ], dmn .ipport )
13401355 assert_equal (pl ["ownerAddress" ], dmn .owner )
13411356 assert_equal (pl ["votingAddress" ], dmn .voting )
13421357 assert_equal (pl ["operatorPubKey" ], dmn .operator_pk )
13431358 assert_equal (pl ["payoutAddress" ], dmn .payee )
1359+ # fix the nullifier
1360+ dmn .nullifier = pl ["nullifier" ]
1361+
13441362
13451363# ------------------------------------------------------
13461364
@@ -1370,17 +1388,18 @@ def __init__(self,
13701388class PivxDMNTestFramework (PivxTestFramework ):
13711389
13721390 def set_base_test_params (self ):
1373- # 1 miner, 1 controller, 6 remote mns
1391+ # 1 miner, 1 controller, 6 remote mns 2 of which shielded
13741392 self .num_nodes = 8
13751393 self .minerPos = 0
13761394 self .controllerPos = 1
13771395 self .setup_clean_chain = True
13781396
1379- def add_new_dmn (self , strType , op_keys = None , from_out = None ):
1397+ def add_new_dmn (self , strType , transparent = True , op_keys = None , from_out = None ):
13801398 self .mns .append (self .register_new_dmn (2 + len (self .mns ),
13811399 self .minerPos ,
13821400 self .controllerPos ,
13831401 strType ,
1402+ transparent ,
13841403 outpoint = from_out ,
13851404 op_blskeys = op_keys ))
13861405
@@ -1440,10 +1459,14 @@ def setup_test(self):
14401459 # Create 6 DMNs and init the remote nodes
14411460 self .log .info ("Initializing masternodes..." )
14421461 for _ in range (2 ):
1443- self .add_new_dmn ("internal" )
1462+ self .add_new_dmn ("internal" , False )
14441463 self .add_new_dmn ("external" )
14451464 self .add_new_dmn ("fund" )
14461465 assert_equal (len (self .mns ), 6 )
1466+ # Sanity check that we have 2 shielded masternodes
1467+ assert_equal (len (self .nodes [self .controllerPos ].listlockunspent ()["shielded" ]), 2 )
1468+ assert_equal (self .mns [0 ].transparent , False )
1469+ assert_equal (self .mns [3 ].transparent , False )
14471470 for mn in self .mns :
14481471 self .nodes [mn .idx ].initmasternode (mn .operator_sk )
14491472 time .sleep (1 )
0 commit comments