Skip to content

Commit f1885d6

Browse files
authored
[CHIA-2947] Actually don't commit puzzle hashes when push=False (#19647)
* Actually dont commit puzzle hashes when push=False * Fix tests * Fix tests * Fix test
1 parent 4994b45 commit f1885d6

File tree

7 files changed

+67
-13
lines changed

7 files changed

+67
-13
lines changed

chia/_tests/wallet/cat_wallet/test_trades.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ async def test_cat_trades(
188188
wallet_node_maker,
189189
client_maker,
190190
full_node,
191+
wallet_environments.tx_config,
191192
authorized_providers,
192193
tail_maker,
193194
proofs_checker_maker,
@@ -198,6 +199,7 @@ async def test_cat_trades(
198199
wallet_node_taker,
199200
client_taker,
200201
full_node,
202+
wallet_environments.tx_config,
201203
authorized_providers,
202204
tail_taker,
203205
proofs_checker_taker,

chia/_tests/wallet/test_signer_protocol.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@
7676
json_deserialize_with_clvm_streamable,
7777
json_serialize_with_clvm_streamable,
7878
)
79-
from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG
8079
from chia.wallet.wallet import Wallet
8180
from chia.wallet.wallet_spend_bundle import WalletSpendBundle
8281
from chia.wallet.wallet_state_manager import WalletStateManager
@@ -614,7 +613,9 @@ async def test_signer_commands(wallet_environments: WalletTestFramework) -> None
614613
)
615614

616615
AMOUNT = uint64(1)
617-
async with wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, sign=False, push=False) as action_scope:
616+
async with wallet_state_manager.new_action_scope(
617+
wallet_environments.tx_config, sign=False, push=False
618+
) as action_scope:
618619
await wallet.generate_signed_transaction([AMOUNT], [bytes32.zeros], action_scope)
619620
[tx] = action_scope.side_effects.transactions
620621

chia/_tests/wallet/test_wallet.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,11 @@ async def test_wallet_clawback_clawback(self, wallet_environments: WalletTestFra
401401

402402
test_fee = 10
403403
resp = await api_0.spend_clawback_coins(
404-
{"coin_ids": [normal_puzhash.hex(), merkle_coin.name().hex()], "fee": test_fee}
404+
{
405+
"coin_ids": [normal_puzhash.hex(), merkle_coin.name().hex()],
406+
"fee": test_fee,
407+
**wallet_environments.tx_config.to_json_dict(),
408+
}
405409
)
406410
assert resp["success"]
407411
assert len(resp["transaction_ids"]) == 1
@@ -530,7 +534,11 @@ async def test_wallet_clawback_sent_self(self, wallet_environments: WalletTestFr
530534
merkle_coin = tx.additions[0] if tx.additions[0].amount == tx_amount else tx.additions[1]
531535
test_fee = 10
532536
resp = await api_0.spend_clawback_coins(
533-
{"coin_ids": [merkle_coin.name().hex(), normal_puzhash.hex()], "fee": test_fee}
537+
{
538+
"coin_ids": [merkle_coin.name().hex(), normal_puzhash.hex()],
539+
"fee": test_fee,
540+
**wallet_environments.tx_config.to_json_dict(),
541+
}
534542
)
535543
assert resp["success"]
536544
assert len(resp["transaction_ids"]) == 1
@@ -663,7 +671,11 @@ async def test_wallet_clawback_claim_manual(self, wallet_environments: WalletTes
663671
merkle_coin = tx.additions[0] if tx.additions[0].amount == tx_amount else tx.additions[1]
664672
test_fee = 10
665673
resp = await api_1.spend_clawback_coins(
666-
{"coin_ids": [merkle_coin.name().hex(), normal_puzhash.hex()], "fee": test_fee}
674+
{
675+
"coin_ids": [merkle_coin.name().hex(), normal_puzhash.hex()],
676+
"fee": test_fee,
677+
**wallet_environments.tx_config.to_json_dict(),
678+
}
667679
)
668680
assert resp["success"]
669681
assert len(resp["transaction_ids"]) == 1
@@ -2133,6 +2145,24 @@ async def test_forced_new_puzzle_hash(self, wallet_environments: WalletTestFrame
21332145
assert tx.spend_bundle is not None
21342146
assert len(list(set(coin.puzzle_hash for coin in tx.spend_bundle.additions()))) == 2
21352147

2148+
@pytest.mark.parametrize(
2149+
"wallet_environments",
2150+
[{"num_environments": 1, "blocks_needed": [1], "reuse_puzhash": True, "trusted": True}],
2151+
indirect=True,
2152+
)
2153+
@pytest.mark.limit_consensus_modes
2154+
@pytest.mark.anyio
2155+
async def test_puzzle_hashes_not_committed(self, wallet_environments: WalletTestFramework) -> None:
2156+
env = wallet_environments.environments[0]
2157+
wallet = env.xch_wallet
2158+
2159+
# Our framework
2160+
async with wallet.wallet_state_manager.new_action_scope(
2161+
wallet_environments.tx_config,
2162+
push=False,
2163+
) as action_scope:
2164+
await action_scope.get_puzzle_hash(wallet.wallet_state_manager, override_reuse_puzhash_with=False)
2165+
21362166

21372167
def test_get_wallet_db_path_v2_r1() -> None:
21382168
root_path: Path = Path("/x/y/z/.chia/mainnet").resolve()

chia/_tests/wallet/vc_wallet/test_vc_wallet.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from chia.wallet.did_wallet.did_wallet import DIDWallet
2626
from chia.wallet.util.query_filter import TransactionTypeFilter
2727
from chia.wallet.util.transaction_type import TransactionType
28-
from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG
28+
from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG, TXConfig
2929
from chia.wallet.util.wallet_types import WalletType
3030
from chia.wallet.vc_wallet.cr_cat_drivers import ProofsChecker, construct_cr_layer
3131
from chia.wallet.vc_wallet.cr_cat_wallet import CRCATWallet
@@ -41,11 +41,12 @@ async def mint_cr_cat(
4141
wallet_node_0: WalletNode,
4242
client_0: WalletRpcClient,
4343
full_node_api: FullNodeSimulator,
44+
tx_config: TXConfig,
4445
authorized_providers: list[bytes32] = [],
4546
tail: Program = Program.to(None),
4647
proofs_checker: ProofsChecker = ProofsChecker(["foo", "bar"]),
4748
) -> None:
48-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
49+
async with wallet_0.wallet_state_manager.new_action_scope(tx_config, push=True) as action_scope:
4950
our_puzzle = await action_scope.get_puzzle(wallet_0.wallet_state_manager)
5051
cat_puzzle: Program = construct_cat_puzzle(
5152
CAT_MOD,
@@ -63,7 +64,7 @@ async def mint_cr_cat(
6364
"amount": CAT_AMOUNT_0,
6465
}
6566
],
66-
DEFAULT_TX_CONFIG,
67+
tx_config,
6768
wallet_id=1,
6869
)
6970
).signed_tx
@@ -314,7 +315,7 @@ async def test_vc_lifecycle(wallet_environments: WalletTestFramework) -> None:
314315
assert get_list_reponse.proof_dict[proof_root] == proofs.key_value_pairs
315316

316317
# Mint CR-CAT
317-
await mint_cr_cat(1, wallet_0, wallet_node_0, client_0, full_node_api, [did_id])
318+
await mint_cr_cat(1, wallet_0, wallet_node_0, client_0, full_node_api, wallet_environments.tx_config, [did_id])
318319
await wallet_environments.process_pending_states(
319320
[
320321
WalletStateTransition(
@@ -823,7 +824,7 @@ async def test_cat_wallet_conversion(
823824
)
824825

825826
did_id = bytes32.zeros
826-
await mint_cr_cat(num_blocks, wallet_0, wallet_node_0, client_0, full_node_api, [did_id])
827+
await mint_cr_cat(num_blocks, wallet_0, wallet_node_0, client_0, full_node_api, DEFAULT_TX_CONFIG, [did_id])
827828
await full_node_api.farm_blocks_to_wallet(count=num_blocks, wallet=wallet_0)
828829
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=20)
829830

chia/wallet/trade_manager.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,16 @@ async def respond_to_offer(
862862
complete_offer, valid_spend_solver = await self.check_for_final_modifications(
863863
Offer.aggregate([offer, take_offer]), solver, inner_action_scope
864864
)
865+
866+
async with action_scope.use() as interface:
867+
if interface.side_effects.get_unused_derivation_record_result is not None:
868+
# This error is of a protection against potential misues of this band-aid solution.
869+
# We should put more thought into how sub-action scopes are generated and what effects
870+
# we might want to push. A ticket to this respect can be found [CHIA-2984].
871+
raise ValueError("Cannot use `respond_to_offer` with existing puzzle hash generation")
872+
interface.side_effects.get_unused_derivation_record_result = (
873+
inner_action_scope.side_effects.get_unused_derivation_record_result
874+
)
865875
self.log.info("COMPLETE OFFER: %s", complete_offer.to_bech32())
866876
assert complete_offer.is_valid()
867877
final_spend_bundle: WalletSpendBundle = complete_offer.to_valid_spend(

chia/wallet/wallet_action_scope.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,5 +165,5 @@ async def new_wallet_action_scope(
165165
extra_spends=self.side_effects.extra_spends,
166166
singleton_records=self.side_effects.singleton_records,
167167
)
168-
if self.side_effects.get_unused_derivation_record_result is not None:
168+
if push and self.side_effects.get_unused_derivation_record_result is not None:
169169
await self.side_effects.get_unused_derivation_record_result.to_standard().commit(wallet_state_manager)

chia/wallet/wallet_state_manager.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,16 @@ def get_wallet(self, id: uint32, required_type: type[TWalletType]) -> TWalletTyp
368368

369369
return wallet
370370

371+
@asynccontextmanager
372+
async def puzzle_hash_db_writer(self) -> AsyncIterator[None]:
373+
async with self.db_wrapper.writer():
374+
old_cache = self.puzzle_store.last_wallet_derivation_index.copy()
375+
try:
376+
yield
377+
except Exception:
378+
self.puzzle_store.last_wallet_derivation_index = old_cache
379+
raise
380+
371381
async def create_more_puzzle_hashes(
372382
self,
373383
from_zero: bool = False,
@@ -382,7 +392,7 @@ async def create_more_puzzle_hashes(
382392
that we can restore the wallet from only the private keys.
383393
"""
384394
try:
385-
async with self.db_wrapper.writer():
395+
async with self.puzzle_hash_db_writer():
386396
if previous_result is not None:
387397
if previous_result.mark_existing_as_used is not mark_existing_as_used:
388398
raise ValueError(
@@ -562,7 +572,7 @@ async def _get_unused_derivation_record(
562572
same public key more than once (for privacy).
563573
"""
564574
try:
565-
async with self.db_wrapper.writer():
575+
async with self.puzzle_hash_db_writer():
566576
if previous_result is not None:
567577
await previous_result.commit(self)
568578
create_more_puzzle_hashes_result: Optional[CreateMorePuzzleHashesResult] = (

0 commit comments

Comments
 (0)