@@ -265,7 +265,8 @@ def run_test(self):
265265 self .test_asset_unlocks (node_wallet , node , pubkey )
266266 self .test_withdrawal_limits (node_wallet , node , pubkey )
267267 self .test_mn_rr (node_wallet , node , pubkey )
268- self .test_withdrawal_fork (node_wallet , node , pubkey )
268+ self .test_withdrawals_fork (node_wallet , node , pubkey )
269+ self .test_v23_fork (node_wallet , node , pubkey )
269270
270271
271272 def test_asset_locks (self , node_wallet , node , pubkey ):
@@ -656,8 +657,8 @@ def test_mn_rr(self, node_wallet, node, pubkey):
656657 self .generate (node , 1 )
657658 assert_equal (locked , self .get_credit_pool_balance ())
658659
659- def test_withdrawal_fork (self , node_wallet , node , pubkey ):
660- self .log .info ("Testing asset unlock after 'withdrawal ' activation..." )
660+ def test_withdrawals_fork (self , node_wallet , node , pubkey ):
661+ self .log .info ("Testing asset unlock after 'withdrawals ' activation..." )
661662 assert softfork_active (node_wallet , 'withdrawals' )
662663 self .log .info (f'post-withdrawals height: { node .getblockcount ()} credit: { self .get_credit_pool_balance ()} ' )
663664
@@ -712,5 +713,64 @@ def test_withdrawal_fork(self, node_wallet, node, pubkey):
712713 self .generate (node , 1 )
713714 self .ensure_tx_is_not_mined (txid_in_block )
714715
716+ def test_v23_fork (self , node_wallet , node , pubkey ):
717+ self .log .info ("Testing asset unlock after 'v23' activation..." )
718+ self .activate_by_name ('v23' , 1050 )
719+ self .log .info (f'post-v23 height: { node .getblockcount ()} credit: { self .get_credit_pool_balance ()} ' )
720+
721+ index = 601
722+ while index < 611 :
723+ self .log .info (f"Generating new Asset Unlock tx, index={ index } ..." )
724+ asset_unlock_tx = self .create_assetunlock (index , COIN , pubkey )
725+ asset_unlock_tx_payload = CAssetUnlockTx ()
726+ asset_unlock_tx_payload .deserialize (BytesIO (asset_unlock_tx .vExtraPayload ))
727+
728+ self .log .info ("Check that Asset Unlock tx is valid for current quorum" )
729+ self .check_mempool_result (tx = asset_unlock_tx , result_expected = {'allowed' : True , 'fees' : {'base' : Decimal (str (tiny_amount / COIN ))}})
730+
731+ quorumHash_str = format (asset_unlock_tx_payload .quorumHash , '064x' )
732+ assert quorumHash_str in node_wallet .quorum ('list' )['llmq_test_platform' ]
733+
734+ while quorumHash_str != node_wallet .quorum ('list' )['llmq_test_platform' ][- 1 ]:
735+ self .log .info ("Generate one more quorum until signing quorum becomes the last one in the list" )
736+ self .mine_quorum_2_nodes ()
737+ self .check_mempool_result (tx = asset_unlock_tx , result_expected = {'allowed' : True , 'fees' : {'base' : Decimal (str (tiny_amount / COIN ))}})
738+
739+ self .log .info ("Generate one more quorum after which signing quorum is gone but Asset Unlock tx is still valid" )
740+ assert quorumHash_str in node_wallet .quorum ('list' )['llmq_test_platform' ]
741+ self .mine_quorum_2_nodes ()
742+ assert quorumHash_str not in node_wallet .quorum ('list' )['llmq_test_platform' ]
743+
744+ if asset_unlock_tx_payload .requestedHeight + HEIGHT_DIFF_EXPIRING > node_wallet .getblockcount ():
745+ self .check_mempool_result (tx = asset_unlock_tx , result_expected = {'allowed' : True , 'fees' : {'base' : Decimal (str (tiny_amount / COIN ))}})
746+ break
747+ else :
748+ self .check_mempool_result (tx = asset_unlock_tx , result_expected = {'allowed' : False , 'reject-reason' : 'bad-assetunlock-too-late' })
749+ self .log .info ("Asset Unlock tx expired, let's try again..." )
750+ index += 1
751+
752+ self .log .info ("Generate one more quorum after which signing quorum becomes too old" )
753+ self .mine_quorum_2_nodes ()
754+ self .check_mempool_result (tx = asset_unlock_tx , result_expected = {'allowed' : False , 'reject-reason' : 'bad-assetunlock-too-old-quorum' })
755+
756+ asset_unlock_tx = self .create_assetunlock (620 , 4000 * COIN + 1 , pubkey )
757+ txid_in_block = self .send_tx (asset_unlock_tx )
758+ self .log .info (f"{ txid_in_block } should not be mined" )
759+ tip_hash = self .generate (node , 1 )[0 ]
760+ assert txid_in_block not in node .getblock (tip_hash )['tx' ]
761+
762+ asset_unlock_tx = self .create_assetunlock (621 , 4000 * COIN , pubkey )
763+ txid_in_block = self .send_tx (asset_unlock_tx )
764+ self .log .info (f"{ txid_in_block } should be mined" )
765+ tip_hash = self .generate (node , 1 )[0 ]
766+ assert txid_in_block in node .getblock (tip_hash )['tx' ]
767+
768+ asset_unlock_tx = self .create_assetunlock (622 , COIN , pubkey )
769+ txid_in_block = self .send_tx (asset_unlock_tx )
770+ self .log .info (f"{ txid_in_block } should not be mined" )
771+ tip_hash = self .generate (node , 1 )[0 ]
772+ assert txid_in_block not in node .getblock (tip_hash )['tx' ]
773+
774+
715775if __name__ == '__main__' :
716776 AssetLocksTest ().main ()
0 commit comments