mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-09-20 16:08:51 +03:00
Merge pull request #12024 from Chia-Network/fee_and_cancel_fix
Fee and cancel fix
This commit is contained in:
commit
c5f7006f95
@ -1,3 +1,4 @@
|
||||
import dataclasses
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
@ -719,9 +720,12 @@ class NFTWallet:
|
||||
new_did_inner_hash=new_did_inner_hash,
|
||||
trade_prices_list=trade_prices_list,
|
||||
)
|
||||
|
||||
spend_bundle = await self.sign(unsigned_spend_bundle)
|
||||
spend_bundle = SpendBundle.aggregate([spend_bundle] + additional_bundles)
|
||||
if chia_tx is not None and chia_tx.spend_bundle is not None:
|
||||
spend_bundle = SpendBundle.aggregate([spend_bundle, chia_tx.spend_bundle])
|
||||
chia_tx = dataclasses.replace(chia_tx, spend_bundle=None)
|
||||
|
||||
tx_list = [
|
||||
TransactionRecord(
|
||||
confirmed_at_height=uint32(0),
|
||||
@ -740,30 +744,11 @@ class NFTWallet:
|
||||
type=uint32(TransactionType.OUTGOING_TX.value),
|
||||
name=spend_bundle.name(),
|
||||
memos=list(compute_memos(spend_bundle).items()),
|
||||
)
|
||||
),
|
||||
]
|
||||
|
||||
if chia_tx is not None:
|
||||
tx_list.append(
|
||||
TransactionRecord(
|
||||
confirmed_at_height=chia_tx.confirmed_at_height,
|
||||
created_at_time=chia_tx.created_at_time,
|
||||
to_puzzle_hash=chia_tx.to_puzzle_hash,
|
||||
amount=chia_tx.amount,
|
||||
fee_amount=chia_tx.fee_amount,
|
||||
confirmed=chia_tx.confirmed,
|
||||
sent=chia_tx.sent,
|
||||
spend_bundle=None,
|
||||
additions=chia_tx.additions,
|
||||
removals=chia_tx.removals,
|
||||
wallet_id=chia_tx.wallet_id,
|
||||
sent_to=chia_tx.sent_to,
|
||||
trade_id=chia_tx.trade_id,
|
||||
type=chia_tx.type,
|
||||
name=chia_tx.name,
|
||||
memos=[],
|
||||
)
|
||||
)
|
||||
tx_list.append(chia_tx)
|
||||
|
||||
return tx_list
|
||||
|
||||
@ -816,7 +801,17 @@ class NFTWallet:
|
||||
puzzle_announcements_to_assert=puzzle_announcements_bytes,
|
||||
)
|
||||
|
||||
if UncurriedNFT.uncurry(nft_coin.full_puzzle).supports_did:
|
||||
uncurried_nft = UncurriedNFT.uncurry(nft_coin.full_puzzle)
|
||||
if uncurried_nft.supports_did:
|
||||
if new_owner is None:
|
||||
# If no new owner was specified and we're sending this to ourselves, let's not reset the DID
|
||||
derivation_record: Optional[
|
||||
DerivationRecord
|
||||
] = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash(
|
||||
payments[0].puzzle_hash
|
||||
)
|
||||
if derivation_record is not None:
|
||||
new_owner = uncurried_nft.owner_did
|
||||
magic_condition = Program.to([-10, new_owner, trade_prices_list, new_did_inner_hash])
|
||||
# TODO: This line is a hack, make_solution should allow us to pass extra conditions to it
|
||||
w_added_magic_condition = Program.to([[], (1, magic_condition.cons(innersol.at("rfr"))), []])
|
||||
@ -828,13 +823,8 @@ class NFTWallet:
|
||||
coin_spend = CoinSpend(nft_coin.coin, nft_coin.full_puzzle, singleton_solution)
|
||||
|
||||
nft_spend_bundle = SpendBundle([coin_spend], G2Element())
|
||||
chia_spend_bundle = SpendBundle([], G2Element())
|
||||
if chia_tx is not None and chia_tx.spend_bundle is not None:
|
||||
chia_spend_bundle = chia_tx.spend_bundle
|
||||
|
||||
unsigned_spend_bundle = SpendBundle.aggregate([nft_spend_bundle, chia_spend_bundle])
|
||||
|
||||
return (unsigned_spend_bundle, chia_tx)
|
||||
return (nft_spend_bundle, chia_tx)
|
||||
|
||||
@staticmethod
|
||||
async def make_nft1_offer(
|
||||
|
@ -1369,14 +1369,13 @@ class WalletStateManager:
|
||||
|
||||
async def create_wallet_for_puzzle_info(self, puzzle_driver: PuzzleInfo, name=None, in_transaction=False):
|
||||
if AssetType(puzzle_driver.type()) in self.asset_to_wallet_map:
|
||||
async with self.lock:
|
||||
await self.asset_to_wallet_map[AssetType(puzzle_driver.type())].create_from_puzzle_info(
|
||||
self,
|
||||
self.main_wallet,
|
||||
puzzle_driver,
|
||||
name,
|
||||
in_transaction,
|
||||
)
|
||||
await self.asset_to_wallet_map[AssetType(puzzle_driver.type())].create_from_puzzle_info(
|
||||
self,
|
||||
self.main_wallet,
|
||||
puzzle_driver,
|
||||
name,
|
||||
in_transaction,
|
||||
)
|
||||
|
||||
async def add_new_wallet(self, wallet: Any, wallet_id: int, create_puzzle_hashes=True, in_transaction=False):
|
||||
self.wallets[uint32(wallet_id)] = wallet
|
||||
|
@ -24,6 +24,7 @@ from chia.wallet.nft_wallet.nft_wallet import NFTWallet
|
||||
from chia.wallet.outer_puzzles import create_asset_id, match_puzzle
|
||||
from chia.wallet.puzzle_drivers import PuzzleInfo
|
||||
from chia.wallet.trading.offer import Offer
|
||||
from chia.wallet.trading.trade_status import TradeStatus
|
||||
from chia.wallet.util.compute_memos import compute_memos
|
||||
|
||||
# from chia.wallet.util.wallet_types import WalletType
|
||||
@ -908,3 +909,126 @@ async def test_nft_offer_request_nft_for_cat(two_wallet_nodes: Any, trusted: Any
|
||||
await time_out_assert(10, wallet_taker.get_confirmed_balance, expected_taker_balance)
|
||||
await time_out_assert(10, cat_wallet_maker.get_confirmed_balance, expected_maker_cat_balance)
|
||||
await time_out_assert(10, cat_wallet_taker.get_confirmed_balance, expected_taker_cat_balance)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"trusted",
|
||||
[True],
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
# @pytest.mark.skip
|
||||
async def test_nft_offer_sell_cancel(two_wallet_nodes: Any, trusted: Any) -> None:
|
||||
num_blocks = 5
|
||||
full_nodes, wallets = two_wallet_nodes
|
||||
full_node_api: FullNodeSimulator = full_nodes[0]
|
||||
full_node_server = full_node_api.server
|
||||
wallet_node_maker, server_0 = wallets[0]
|
||||
wallet_maker = wallet_node_maker.wallet_state_manager.main_wallet
|
||||
|
||||
ph_maker = await wallet_maker.get_new_puzzlehash()
|
||||
ph_token = bytes32(token_bytes())
|
||||
|
||||
if trusted:
|
||||
wallet_node_maker.config["trusted_peers"] = {
|
||||
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
||||
}
|
||||
else:
|
||||
wallet_node_maker.config["trusted_peers"] = {}
|
||||
|
||||
await server_0.start_client(PeerInfo("localhost", uint16(full_node_server._port)), None)
|
||||
|
||||
for _ in range(1, num_blocks):
|
||||
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_maker))
|
||||
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
||||
|
||||
funds = sum(
|
||||
[calculate_pool_reward(uint32(i)) + calculate_base_farmer_reward(uint32(i)) for i in range(1, num_blocks)]
|
||||
)
|
||||
|
||||
await time_out_assert(10, wallet_maker.get_unconfirmed_balance, funds)
|
||||
await time_out_assert(10, wallet_maker.get_confirmed_balance, funds)
|
||||
|
||||
did_wallet_maker: DIDWallet = await DIDWallet.create_new_did_wallet(
|
||||
wallet_node_maker.wallet_state_manager, wallet_maker, uint64(1)
|
||||
)
|
||||
spend_bundle_list = await wallet_node_maker.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(
|
||||
wallet_maker.id()
|
||||
)
|
||||
|
||||
spend_bundle = spend_bundle_list[0].spend_bundle
|
||||
await time_out_assert_not_none(5, full_node_api.full_node.mempool_manager.get_spendbundle, spend_bundle.name())
|
||||
|
||||
for _ in range(1, num_blocks):
|
||||
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
||||
|
||||
await time_out_assert(15, wallet_maker.get_pending_change_balance, 0)
|
||||
await time_out_assert(10, wallet_maker.get_unconfirmed_balance, funds - 1)
|
||||
await time_out_assert(10, wallet_maker.get_confirmed_balance, funds - 1)
|
||||
|
||||
hex_did_id = did_wallet_maker.get_my_DID()
|
||||
did_id = bytes32.fromhex(hex_did_id)
|
||||
target_puzhash = ph_maker
|
||||
royalty_puzhash = ph_maker
|
||||
royalty_basis_pts = uint16(200)
|
||||
|
||||
nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
|
||||
wallet_node_maker.wallet_state_manager, wallet_maker, name="NFT WALLET DID 1", did_id=did_id
|
||||
)
|
||||
metadata = Program.to(
|
||||
[
|
||||
("u", ["https://www.chia.net/img/branding/chia-logo.svg"]),
|
||||
("h", "0xD4584AD463139FA8C0D9F68F4B59F185"),
|
||||
]
|
||||
)
|
||||
|
||||
sb = await nft_wallet_maker.generate_new_nft(
|
||||
metadata,
|
||||
target_puzhash,
|
||||
royalty_puzhash,
|
||||
royalty_basis_pts,
|
||||
did_id,
|
||||
)
|
||||
assert sb
|
||||
# ensure hints are generated
|
||||
assert compute_memos(sb)
|
||||
await time_out_assert_not_none(5, full_node_api.full_node.mempool_manager.get_spendbundle, sb.name())
|
||||
|
||||
for i in range(1, num_blocks):
|
||||
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_token))
|
||||
|
||||
await time_out_assert(10, len, 1, nft_wallet_maker.my_nft_coins)
|
||||
|
||||
# maker create offer: NFT for xch
|
||||
trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
|
||||
|
||||
coins_maker = nft_wallet_maker.my_nft_coins
|
||||
assert len(coins_maker) == 1
|
||||
|
||||
nft_to_offer = coins_maker[0]
|
||||
nft_to_offer_info: Optional[PuzzleInfo] = match_puzzle(nft_to_offer.full_puzzle)
|
||||
nft_to_offer_asset_id: bytes32 = create_asset_id(nft_to_offer_info) # type: ignore
|
||||
xch_requested = 1000
|
||||
maker_fee = uint64(433)
|
||||
|
||||
offer_did_nft_for_xch = {nft_to_offer_asset_id: -1, wallet_maker.id(): xch_requested}
|
||||
|
||||
success, trade_make, error = await trade_manager_maker.create_offer_for_ids(
|
||||
offer_did_nft_for_xch, {}, fee=maker_fee
|
||||
)
|
||||
|
||||
FEE = uint64(2000000000000)
|
||||
txs = await trade_manager_maker.cancel_pending_offer_safely(trade_make.trade_id, fee=FEE)
|
||||
|
||||
async def get_trade_and_status(trade_manager: Any, trade: Any) -> TradeStatus:
|
||||
trade_rec = await trade_manager.get_trade_by_id(trade.trade_id)
|
||||
return TradeStatus(trade_rec.status)
|
||||
|
||||
await time_out_assert(15, get_trade_and_status, TradeStatus.PENDING_CANCEL, trade_manager_maker, trade_make)
|
||||
for tx in txs:
|
||||
if tx.spend_bundle is not None:
|
||||
await time_out_assert(15, tx_in_pool, True, full_node_api.full_node.mempool_manager, tx.spend_bundle.name())
|
||||
|
||||
for i in range(1, num_blocks):
|
||||
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(bytes32([0] * 32)))
|
||||
|
||||
await time_out_assert(15, get_trade_and_status, TradeStatus.CANCELLED, trade_manager_maker, trade_make)
|
||||
|
Loading…
Reference in New Issue
Block a user