use crate::blocks::burn::BurnTransaction; use crate::common::network_paths_and_settings::block_extension_and_paths; use crate::common::nft_assets::nft_asset_name; use crate::decode; use crate::records::balance_sheet::operations::balance_sheet_operation_with_db; use crate::records::record_chain::nft_provenance::remove_nft_history_entry; use crate::records::record_chain::token_provenance::remove_token_history_entry; use crate::records::record_chain::wallet_tx_index::remove_wallet_transaction_index; use crate::sled::Db; pub async fn undo_burn_transaction(transaction: BurnTransaction, mining_receiver: &str, db: &Db) { // Reverse the burn fee and burned-asset balance movement before // restoring the live token or NFT state back into the active chain. let operand_subtraction = "subtraction"; let operand_addition = "addition"; let ( _network_name, _padded_base_coin, type_str, _torrentpath, _wallet_path, _blockpath, _db_path, _balance_path, _log_path, ) = block_extension_and_paths(); let burned_asset = nft_asset_name( &transaction.unsigned_burn.coin, transaction.unsigned_burn.nft_series, ); // Remove the miner fee, refund the burner fee, and return the burned asset // to the burner balance. let _ = balance_sheet_operation_with_db( db, mining_receiver, transaction.unsigned_burn.txfee, &type_str, operand_subtraction, ); let _ = balance_sheet_operation_with_db( db, &transaction.unsigned_burn.address, transaction.unsigned_burn.txfee, &type_str, operand_addition, ); let _ = balance_sheet_operation_with_db( db, &transaction.unsigned_burn.address, transaction.unsigned_burn.value, &burned_asset, operand_addition, ); let hash_binary = decode(&transaction.unsigned_burn.hash().await).unwrap(); let _ = remove_wallet_transaction_index( db, &[&transaction.unsigned_burn.address, mining_receiver], &hash_binary, ); // Delete the txid lookup inserted when the burn was saved. let txid_tree = db.open_tree("txid").unwrap(); txid_tree.remove(hash_binary.clone()).unwrap(); // Restore NFT rows directly, or add the burned amount back into the // fungible token supply if this burn targeted a token asset. let nft_tree = db.open_tree("nfts").unwrap(); let nft_origin_tree = db.open_tree("nft_origins").unwrap(); if nft_origin_tree .contains_key(burned_asset.as_bytes()) .unwrap_or(false) { // NFT burns remove the live NFT row; rollback restores the row and // removes the burn from NFT history. let _ = remove_nft_history_entry(db, &burned_asset, &hash_binary); let _ = nft_tree.insert(burned_asset.as_bytes(), b"1"); } else { // Token burns reduce supply; rollback adds the burned amount back. let _ = remove_token_history_entry(db, &transaction.unsigned_burn.coin, &hash_binary); let token_tree = db.open_tree("tokens").unwrap(); let current_supply = token_tree .get(transaction.unsigned_burn.coin.as_bytes()) .unwrap() .map(|bytes| { let mut supply_bytes = [0u8; 8]; supply_bytes.copy_from_slice(bytes.as_ref()); u64::from_le_bytes(supply_bytes) }) .unwrap_or(0); let restored_supply = current_supply.saturating_add(transaction.unsigned_burn.value); let _ = token_tree.insert( transaction.unsigned_burn.coin.as_bytes(), &restored_supply.to_le_bytes(), ); } }