Merge commit '219667b6d8547eae7c7a72b1dc699201abfd8843' into checkpoint/main_from_release_2.1.2_219667b6d8547eae7c7a72b1dc699201abfd8843

This commit is contained in:
Amine Khaldi 2023-12-11 22:25:45 +01:00
commit f91c9f4422
No known key found for this signature in database
GPG Key ID: B1C074FFC904E2D9
3 changed files with 203 additions and 2 deletions

View File

@ -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")

View File

@ -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(

View File

@ -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