@@ -5351,3 +5351,163 @@ fn reorg_tokens_tx_with_simple_tx(#[case] seed: Seed) {
53515351 let new_chain_block_id = tf. create_chain ( & tf. genesis ( ) . get_id ( ) . into ( ) , 2 , & mut rng) . unwrap ( ) ;
53525352 assert_eq ! ( new_chain_block_id, tf. best_block_id( ) ) ;
53535353}
5354+
5355+ #[ rstest]
5356+ #[ trace]
5357+ #[ case( Seed :: from_entropy( ) ) ]
5358+ fn issue_same_token_alternative_pos_chain ( #[ case] seed : Seed ) {
5359+ use chainstate_test_framework:: create_stake_pool_data_with_all_reward_to_staker;
5360+ use common:: {
5361+ chain:: { config:: create_unit_test_config, PoolId } ,
5362+ primitives:: H256 ,
5363+ } ;
5364+ use crypto:: vrf:: { VRFKeyKind , VRFPrivateKey } ;
5365+
5366+ utils:: concurrency:: model ( move || {
5367+ let mut rng = make_seedable_rng ( seed) ;
5368+ let ( vrf_sk, vrf_pk) = VRFPrivateKey :: new_from_rng ( & mut rng, VRFKeyKind :: Schnorrkel ) ;
5369+
5370+ let genesis_pool_id = PoolId :: new ( H256 :: random_using ( & mut rng) ) ;
5371+ let amount_to_stake = create_unit_test_config ( ) . min_stake_pool_pledge ( ) ;
5372+
5373+ let ( stake_pool_data, staking_sk) = create_stake_pool_data_with_all_reward_to_staker (
5374+ & mut rng,
5375+ amount_to_stake,
5376+ vrf_pk. clone ( ) ,
5377+ ) ;
5378+
5379+ let chain_config = chainstate_test_framework:: create_chain_config_with_staking_pool (
5380+ & mut rng,
5381+ ( amount_to_stake * 2 ) . unwrap ( ) ,
5382+ genesis_pool_id,
5383+ stake_pool_data,
5384+ )
5385+ . build ( ) ;
5386+ let target_block_time = chain_config. target_block_spacing ( ) ;
5387+ let mut tf = TestFramework :: builder ( & mut rng) . with_chain_config ( chain_config) . build ( ) ;
5388+ tf. progress_time_seconds_since_epoch ( target_block_time. as_secs ( ) ) ;
5389+
5390+ let genesis_block_id = tf. genesis ( ) . get_id ( ) ;
5391+ let token_supply_change_fee =
5392+ tf. chainstate . get_chain_config ( ) . token_supply_change_fee ( BlockHeight :: zero ( ) ) ;
5393+
5394+ //issue a token
5395+ let issuance = make_issuance (
5396+ & mut rng,
5397+ TokenTotalSupply :: Fixed ( Amount :: from_atoms ( 100 ) ) ,
5398+ IsTokenFreezable :: No ,
5399+ ) ;
5400+ let issue_token_tx = TransactionBuilder :: new ( )
5401+ . add_input (
5402+ TxInput :: from_utxo ( genesis_block_id. into ( ) , 0 ) ,
5403+ InputWitness :: NoSignature ( None ) ,
5404+ )
5405+ . add_output ( TxOutput :: Transfer (
5406+ OutputValue :: Coin ( token_supply_change_fee) ,
5407+ Destination :: AnyoneCanSpend ,
5408+ ) )
5409+ . add_output ( TxOutput :: IssueFungibleToken ( Box :: new ( issuance. clone ( ) ) ) )
5410+ . build ( ) ;
5411+ let token_id = make_token_id ( issue_token_tx. transaction ( ) . inputs ( ) ) . unwrap ( ) ;
5412+ let tx_id = issue_token_tx. transaction ( ) . get_id ( ) ;
5413+ tf. make_pos_block_builder ( )
5414+ . with_stake_pool_id ( genesis_pool_id)
5415+ . with_stake_spending_key ( staking_sk. clone ( ) )
5416+ . with_vrf_key ( vrf_sk. clone ( ) )
5417+ . add_transaction ( issue_token_tx)
5418+ . build_and_process ( & mut rng)
5419+ . unwrap ( ) ;
5420+
5421+ // Mint some tokens to increase circulating supply
5422+ let mint_block_index = tf
5423+ . make_pos_block_builder ( )
5424+ . with_stake_pool_id ( genesis_pool_id)
5425+ . with_stake_spending_key ( staking_sk. clone ( ) )
5426+ . with_vrf_key ( vrf_sk. clone ( ) )
5427+ . add_transaction (
5428+ TransactionBuilder :: new ( )
5429+ . add_input (
5430+ TxInput :: from_command (
5431+ AccountNonce :: new ( 0 ) ,
5432+ AccountCommand :: MintTokens ( token_id, Amount :: from_atoms ( 5 ) ) ,
5433+ ) ,
5434+ InputWitness :: NoSignature ( None ) ,
5435+ )
5436+ . add_input (
5437+ UtxoOutPoint :: new ( tx_id. into ( ) , 0 ) . into ( ) ,
5438+ InputWitness :: NoSignature ( None ) ,
5439+ )
5440+ . add_output ( TxOutput :: Transfer (
5441+ OutputValue :: TokenV1 ( token_id, Amount :: from_atoms ( 5 ) ) ,
5442+ Destination :: AnyoneCanSpend ,
5443+ ) )
5444+ . build ( ) ,
5445+ )
5446+ . build_and_process ( & mut rng)
5447+ . unwrap ( )
5448+ . unwrap ( ) ;
5449+ assert_eq ! (
5450+ Id :: <GenBlock >:: from( * mint_block_index. block_id( ) ) ,
5451+ tf. best_block_id( )
5452+ ) ;
5453+
5454+ // issue same token in alternative chain
5455+ let alt_block_a = tf
5456+ . make_pos_block_builder ( )
5457+ . with_parent ( genesis_block_id. into ( ) )
5458+ . with_stake_pool_id ( genesis_pool_id)
5459+ . with_stake_spending_key ( staking_sk. clone ( ) )
5460+ . with_vrf_key ( vrf_sk. clone ( ) )
5461+ . add_transaction (
5462+ TransactionBuilder :: new ( )
5463+ . add_input (
5464+ TxInput :: from_utxo ( genesis_block_id. into ( ) , 0 ) ,
5465+ InputWitness :: NoSignature ( None ) ,
5466+ )
5467+ . add_output ( TxOutput :: Transfer (
5468+ OutputValue :: Coin ( ( token_supply_change_fee * 2 ) . unwrap ( ) ) ,
5469+ Destination :: AnyoneCanSpend ,
5470+ ) )
5471+ . add_output ( TxOutput :: IssueFungibleToken ( Box :: new ( issuance) ) )
5472+ . build ( ) ,
5473+ )
5474+ . build ( & mut rng) ;
5475+ let alt_block_a_id = alt_block_a. get_id ( ) ;
5476+ tf. process_block ( alt_block_a, BlockSource :: Local ) . unwrap ( ) ;
5477+
5478+ assert_ne ! ( Id :: <GenBlock >:: from( alt_block_a_id) , tf. best_block_id( ) ) ;
5479+ assert_eq ! (
5480+ Id :: <GenBlock >:: from( * mint_block_index. block_id( ) ) ,
5481+ tf. best_block_id( )
5482+ ) ;
5483+
5484+ let alt_block_b = tf
5485+ . make_pos_block_builder ( )
5486+ . with_parent ( alt_block_a_id. into ( ) )
5487+ . with_stake_pool_id ( genesis_pool_id)
5488+ . with_stake_spending_key ( staking_sk. clone ( ) )
5489+ . with_vrf_key ( vrf_sk. clone ( ) )
5490+ . build ( & mut rng) ;
5491+ let alt_block_b_id = alt_block_b. get_id ( ) ;
5492+ tf. process_block ( alt_block_b, BlockSource :: Local ) . unwrap ( ) ;
5493+
5494+ assert_ne ! ( Id :: <GenBlock >:: from( alt_block_b_id) , tf. best_block_id( ) ) ;
5495+ assert_eq ! (
5496+ Id :: <GenBlock >:: from( * mint_block_index. block_id( ) ) ,
5497+ tf. best_block_id( )
5498+ ) ;
5499+
5500+ // Trigger a reorg
5501+ let alt_block_c = tf
5502+ . make_pos_block_builder ( )
5503+ . with_parent ( alt_block_b_id. into ( ) )
5504+ . with_stake_pool_id ( genesis_pool_id)
5505+ . with_stake_spending_key ( staking_sk. clone ( ) )
5506+ . with_vrf_key ( vrf_sk. clone ( ) )
5507+ . build ( & mut rng) ;
5508+ let alt_block_c_id = alt_block_c. get_id ( ) ;
5509+ tf. process_block ( alt_block_c, BlockSource :: Local ) . unwrap ( ) ;
5510+
5511+ assert_eq ! ( Id :: <GenBlock >:: from( alt_block_c_id) , tf. best_block_id( ) ) ;
5512+ } ) ;
5513+ }
0 commit comments