mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-12-01 11:27:10 +03:00
Merge commit '219667b6d8547eae7c7a72b1dc699201abfd8843' into checkpoint/main_from_release_2.1.2_219667b6d8547eae7c7a72b1dc699201abfd8843
This commit is contained in:
commit
f91c9f4422
@ -178,7 +178,7 @@ def dao_create_cmd(
|
||||
) -> None:
|
||||
from .dao_funcs import create_dao_wallet
|
||||
|
||||
if self_destruct == proposal_timelock:
|
||||
if self_destruct == proposal_timelock: # pragma: no cover
|
||||
raise ValueError("Self Destruct and Proposal Timelock cannot be the same value")
|
||||
|
||||
print("Creating new DAO")
|
||||
|
@ -789,7 +789,7 @@ class WalletStateManager:
|
||||
# Check if the coin is a DAO CAT
|
||||
dao_cat_args = match_dao_cat_puzzle(uncurried)
|
||||
if dao_cat_args:
|
||||
return await self.handle_dao_cat(dao_cat_args, parent_coin_state, coin_state, coin_spend), None
|
||||
return await self.handle_dao_cat(dao_cat_args, parent_coin_state, coin_state, coin_spend, fork_height), None
|
||||
|
||||
# Check if the coin is a CAT
|
||||
cat_curried_args = match_cat_puzzle(uncurried)
|
||||
@ -1021,6 +1021,7 @@ class WalletStateManager:
|
||||
parent_coin_state: CoinState,
|
||||
coin_state: CoinState,
|
||||
coin_spend: CoinSpend,
|
||||
fork_height: Optional[uint32],
|
||||
) -> Optional[WalletIdentifier]:
|
||||
"""
|
||||
Handle the new coin when it is a DAO CAT
|
||||
@ -1032,6 +1033,19 @@ class WalletStateManager:
|
||||
assert isinstance(wallet, DAOCATWallet)
|
||||
if wallet.dao_cat_info.limitations_program_hash == asset_id:
|
||||
return WalletIdentifier.create(wallet)
|
||||
# Found a DAO_CAT, but we don't have a wallet for it. Add to unacknowledged
|
||||
await self.interested_store.add_unacknowledged_token(
|
||||
asset_id,
|
||||
CATWallet.default_wallet_name_for_unknown_cat(asset_id.hex()),
|
||||
None if parent_coin_state.spent_height is None else uint32(parent_coin_state.spent_height),
|
||||
parent_coin_state.coin.puzzle_hash,
|
||||
)
|
||||
await self.interested_store.add_unacknowledged_coin_state(
|
||||
asset_id,
|
||||
coin_state,
|
||||
fork_height,
|
||||
)
|
||||
self.state_changed("added_stray_cat")
|
||||
return None # pragma: no cover
|
||||
|
||||
async def handle_cat(
|
||||
|
@ -3348,3 +3348,190 @@ async def test_dao_votes(
|
||||
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
||||
|
||||
assert dao_wallet_0.dao_info.proposals_list[3].amount_voted == 210000
|
||||
|
||||
|
||||
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
||||
@pytest.mark.parametrize(
|
||||
"trusted",
|
||||
[True, False],
|
||||
)
|
||||
@pytest.mark.anyio
|
||||
async def test_dao_resync(
|
||||
self_hostname: str, two_wallet_nodes: SimulatorsAndWallets, trusted: bool, consensus_mode: ConsensusMode
|
||||
) -> None:
|
||||
full_nodes, wallets, _ = two_wallet_nodes
|
||||
full_node_api = full_nodes[0]
|
||||
full_node_server = full_node_api.server
|
||||
wallet_node_0, server_0 = wallets[0]
|
||||
wallet_node_1, server_1 = wallets[1]
|
||||
wallet_api_0 = WalletRpcApi(wallet_node_0)
|
||||
wallet_api_1 = WalletRpcApi(wallet_node_1)
|
||||
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
||||
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
||||
ph = await wallet_0.get_new_puzzlehash()
|
||||
ph_1 = await wallet_1.get_new_puzzlehash()
|
||||
|
||||
if trusted:
|
||||
wallet_node_0.config["trusted_peers"] = {
|
||||
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
||||
}
|
||||
wallet_node_1.config["trusted_peers"] = {
|
||||
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
||||
}
|
||||
else:
|
||||
wallet_node_0.config["trusted_peers"] = {}
|
||||
wallet_node_1.config["trusted_peers"] = {}
|
||||
|
||||
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
||||
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
||||
|
||||
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
|
||||
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_1))
|
||||
|
||||
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
||||
|
||||
await time_out_assert(20, wallet_0.get_confirmed_balance, funds)
|
||||
await time_out_assert(20, full_node_api.wallet_is_synced, True, wallet_node_0)
|
||||
|
||||
cat_amt = 2000
|
||||
dao_rules = DAORules(
|
||||
proposal_timelock=uint64(10),
|
||||
soft_close_length=uint64(5),
|
||||
attendance_required=uint64(1000), # 10%
|
||||
pass_percentage=uint64(5100), # 51%
|
||||
self_destruct_length=uint64(20),
|
||||
oracle_spend_delay=uint64(10),
|
||||
proposal_minimum_amount=uint64(1),
|
||||
)
|
||||
|
||||
fee = uint64(10)
|
||||
fee_for_cat = uint64(20)
|
||||
dao_wallet_0 = await DAOWallet.create_new_dao_and_wallet(
|
||||
wallet_node_0.wallet_state_manager,
|
||||
wallet_0,
|
||||
uint64(cat_amt * 2),
|
||||
dao_rules,
|
||||
DEFAULT_TX_CONFIG,
|
||||
fee=fee,
|
||||
fee_for_cat=fee_for_cat,
|
||||
)
|
||||
assert dao_wallet_0 is not None
|
||||
|
||||
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
||||
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
||||
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
||||
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
||||
|
||||
treasury_id = dao_wallet_0.dao_info.treasury_id
|
||||
|
||||
# get the cat wallets
|
||||
cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.cat_wallet_id]
|
||||
# dao_cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.dao_cat_wallet_id]
|
||||
|
||||
# Create the other user's wallet from the treasury id
|
||||
dao_wallet_1 = await DAOWallet.create_new_dao_wallet_for_existing_dao(
|
||||
wallet_node_1.wallet_state_manager,
|
||||
wallet_1,
|
||||
treasury_id,
|
||||
)
|
||||
assert dao_wallet_1 is not None
|
||||
assert dao_wallet_0.dao_info.treasury_id == dao_wallet_1.dao_info.treasury_id
|
||||
|
||||
# Get the cat wallets for wallet_1
|
||||
cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.cat_wallet_id]
|
||||
|
||||
# Send some cats to the dao_cat lockup
|
||||
dao_cat_amt = uint64(100)
|
||||
txs = await dao_wallet_0.enter_dao_cat_voting_mode(dao_cat_amt, DEFAULT_TX_CONFIG)
|
||||
for tx in txs:
|
||||
await wallet_0.wallet_state_manager.add_pending_transaction(tx)
|
||||
|
||||
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
||||
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
||||
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
||||
|
||||
# send some cats from wallet_0 to wallet_1 so we can test voting
|
||||
cat_txs = await cat_wallet_0.generate_signed_transaction([cat_amt], [ph_1], DEFAULT_TX_CONFIG)
|
||||
await wallet_0.wallet_state_manager.add_pending_transaction(cat_txs[0])
|
||||
|
||||
await full_node_api.wait_transaction_records_entered_mempool(records=cat_txs, timeout=60)
|
||||
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
||||
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
||||
|
||||
await time_out_assert(10, cat_wallet_1.get_confirmed_balance, cat_amt)
|
||||
|
||||
recipient_puzzle_hash = await wallet_1.get_new_puzzlehash()
|
||||
proposal_amount_1 = uint64(9998)
|
||||
xch_proposal_inner = generate_simple_proposal_innerpuz(
|
||||
treasury_id,
|
||||
[recipient_puzzle_hash],
|
||||
[proposal_amount_1],
|
||||
[None],
|
||||
)
|
||||
proposal_tx = await dao_wallet_0.generate_new_proposal(xch_proposal_inner, DEFAULT_TX_CONFIG, uint64(10))
|
||||
await wallet_0.wallet_state_manager.add_pending_transaction(proposal_tx)
|
||||
await full_node_api.wait_transaction_records_entered_mempool(records=[proposal_tx], timeout=60)
|
||||
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
||||
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
||||
|
||||
# make another proposal spending all the dao_cats
|
||||
xch_proposal_inner = generate_simple_proposal_innerpuz(
|
||||
treasury_id,
|
||||
[recipient_puzzle_hash],
|
||||
[proposal_amount_1],
|
||||
[None],
|
||||
)
|
||||
proposal_tx = await dao_wallet_0.generate_new_proposal(xch_proposal_inner, DEFAULT_TX_CONFIG)
|
||||
await wallet_0.wallet_state_manager.add_pending_transaction(proposal_tx)
|
||||
await full_node_api.wait_transaction_records_entered_mempool(records=[proposal_tx], timeout=60)
|
||||
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
||||
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
||||
|
||||
# set flag to reset wallet sync data on start
|
||||
await wallet_api_0.set_wallet_resync_on_startup({"enable": True})
|
||||
fingerprint_0 = wallet_node_0.logged_in_fingerprint
|
||||
await wallet_api_1.set_wallet_resync_on_startup({"enable": True})
|
||||
fingerprint_1 = wallet_node_1.logged_in_fingerprint
|
||||
# Delete tx records
|
||||
await wallet_node_0.wallet_state_manager.tx_store.rollback_to_block(0)
|
||||
wallet_node_0._close()
|
||||
await wallet_node_0._await_closed()
|
||||
wallet_node_1._close()
|
||||
await wallet_node_1._await_closed()
|
||||
wallet_node_0.config["database_path"] = "wallet/db/blockchain_wallet_v2_test_1_CHALLENGE_KEY.sqlite"
|
||||
wallet_node_1.config["database_path"] = "wallet/db/blockchain_wallet_v2_test_2_CHALLENGE_KEY.sqlite"
|
||||
# Start resync
|
||||
await wallet_node_0._start_with_fingerprint(fingerprint_0)
|
||||
await wallet_node_1._start_with_fingerprint(fingerprint_1)
|
||||
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
||||
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
||||
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
||||
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=20)
|
||||
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_1, timeout=20)
|
||||
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
||||
|
||||
assert len(await wallet_node_0.wallet_state_manager.get_all_wallet_info_entries()) == 1
|
||||
|
||||
new_dao_wallet = await DAOWallet.create_new_dao_wallet_for_existing_dao(
|
||||
wallet_node_0.wallet_state_manager,
|
||||
wallet_0,
|
||||
treasury_id,
|
||||
)
|
||||
|
||||
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
||||
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=20)
|
||||
assert len(await wallet_node_0.wallet_state_manager.get_all_wallet_info_entries()) == 4
|
||||
new_cat_wallet = new_dao_wallet.wallet_state_manager.wallets[new_dao_wallet.dao_info.cat_wallet_id]
|
||||
new_dao_cat_wallet = new_dao_wallet.wallet_state_manager.wallets[new_dao_wallet.dao_info.dao_cat_wallet_id]
|
||||
|
||||
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
||||
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=20)
|
||||
|
||||
# Check the new wallets have the right balances
|
||||
await time_out_assert(20, new_cat_wallet.get_confirmed_balance, cat_amt - dao_cat_amt)
|
||||
await time_out_assert(20, new_dao_cat_wallet.get_confirmed_balance, dao_cat_amt)
|
||||
|
||||
# Check the proposals are found and accurate
|
||||
assert len(new_dao_wallet.dao_info.proposals_list) == 2
|
||||
assert new_dao_wallet.dao_info.proposals_list[0].yes_votes == 10
|
||||
assert new_dao_wallet.dao_info.proposals_list[1].yes_votes == 100
|
||||
|
Loading…
Reference in New Issue
Block a user