Skip to content

Commit eadce79

Browse files
authored
catchup: into long_lived/datalayer_merkle_blob from main @ eca97fa (#20095)
Source hash: eca97fa Remaining commits: 0
2 parents 8db5038 + 586bfea commit eadce79

15 files changed

+179
-150
lines changed

.github/workflows/test-install-scripts.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ concurrency:
2020
group: ${{ github.event_name == 'pull_request' && format('{0}-{1}', github.workflow_ref, github.event.pull_request.number) || github.run_id }}
2121
cancel-in-progress: true
2222

23+
defaults:
24+
run:
25+
shell: bash
26+
2327
jobs:
2428
test_scripts:
2529
name: Native ${{ matrix.os.emoji }} ${{ matrix.arch.emoji }} ${{ matrix.development.name }} - ${{ matrix.editable.name }}
@@ -109,6 +113,7 @@ jobs:
109113
110114
- name: Run install-gui script (Windows)
111115
if: matrix.os.matrix == 'windows'
116+
shell: pwsh
112117
run: |
113118
./Install-gui.ps1
114119

chia/_tests/cmds/wallet/test_notifications.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
from __future__ import annotations
22

33
from pathlib import Path
4-
from typing import cast
54

65
from chia_rs.sized_bytes import bytes32
76
from chia_rs.sized_ints import uint32, uint64
87

98
from chia._tests.cmds.cmd_test_utils import TestRpcClients, TestWalletRpcClient, logType, run_cli_command_and_assert
10-
from chia._tests.cmds.wallet.test_consts import FINGERPRINT, FINGERPRINT_ARG, get_bytes32
9+
from chia._tests.cmds.wallet.test_consts import FINGERPRINT, FINGERPRINT_ARG, STD_TX, STD_UTX, get_bytes32
1110
from chia.util.bech32m import encode_puzzle_hash
12-
from chia.wallet.conditions import ConditionValidTimes
11+
from chia.wallet.conditions import Condition, ConditionValidTimes
1312
from chia.wallet.notification_store import Notification
14-
from chia.wallet.transaction_record import TransactionRecord
15-
from chia.wallet.wallet_request_types import DeleteNotifications, GetNotifications, GetNotificationsResponse
13+
from chia.wallet.util.tx_config import TXConfig
14+
from chia.wallet.wallet_request_types import (
15+
DeleteNotifications,
16+
GetNotifications,
17+
GetNotificationsResponse,
18+
SendNotification,
19+
SendNotificationResponse,
20+
)
1621

1722
test_condition_valid_times: ConditionValidTimes = ConditionValidTimes(min_time=uint64(100), max_time=uint64(150))
1823

@@ -26,20 +31,17 @@ def test_notifications_send(capsys: object, get_test_cli_clients: tuple[TestRpcC
2631
class NotificationsSendRpcClient(TestWalletRpcClient):
2732
async def send_notification(
2833
self,
29-
target: bytes32,
30-
msg: bytes,
31-
amount: uint64,
32-
fee: uint64 = uint64(0),
33-
push: bool = True,
34+
request: SendNotification,
35+
tx_config: TXConfig,
36+
extra_conditions: tuple[Condition, ...] = tuple(),
3437
timelock_info: ConditionValidTimes = ConditionValidTimes(),
35-
) -> TransactionRecord:
36-
self.add_to_log("send_notification", (target, msg, amount, fee, push, timelock_info))
37-
38-
class FakeTransactionRecord:
39-
def __init__(self, name: str) -> None:
40-
self.name = name
38+
) -> SendNotificationResponse:
39+
self.add_to_log(
40+
"send_notification",
41+
(request.target, request.message, request.amount, request.fee, request.push, timelock_info),
42+
)
4143

42-
return cast(TransactionRecord, FakeTransactionRecord(get_bytes32(2).hex()))
44+
return SendNotificationResponse([STD_UTX], [STD_TX], tx=STD_TX)
4345

4446
inst_rpc_client = NotificationsSendRpcClient()
4547
test_rpc_clients.wallet_rpc_client = inst_rpc_client

chia/_tests/core/mempool/test_mempool_manager.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,6 @@ def make_bundle_spends_map_and_fee(
579579
bundle_coin_spends[coin_id] = BundleCoinSpend(
580580
coin_spend=coin_spend,
581581
eligible_for_dedup=bool(spend_conds.flags & ELIGIBLE_FOR_DEDUP),
582-
eligible_for_fast_forward=bool(spend_conds.flags & ELIGIBLE_FOR_FF),
583582
additions=additions,
584583
cost=uint64(spend_conds.condition_cost + spend_conds.execution_cost),
585584
latest_singleton_lineage=UnspentLineageInfo(coin_id, coin_spend.coin.parent_coin_info, bytes32([0] * 32))
@@ -890,9 +889,13 @@ def mk_bcs(coin_spend: CoinSpend, flags: int = 0) -> BundleCoinSpend:
890889
return BundleCoinSpend(
891890
coin_spend=coin_spend,
892891
eligible_for_dedup=bool(flags & ELIGIBLE_FOR_DEDUP),
893-
eligible_for_fast_forward=bool(flags & ELIGIBLE_FOR_FF),
894892
additions=[],
895893
cost=uint64(0),
894+
latest_singleton_lineage=UnspentLineageInfo(
895+
coin_spend.coin.name(), coin_spend.coin.parent_coin_info, bytes32([0] * 32)
896+
)
897+
if flags & ELIGIBLE_FOR_FF
898+
else None,
896899
)
897900

898901

@@ -1119,8 +1122,7 @@ def make_test_coins() -> list[Coin]:
11191122
],
11201123
)
11211124
def test_can_replace(existing_items: list[MempoolItem], new_item: MempoolItem, expected: bool) -> None:
1122-
removals = {c.name() for c in new_item.spend_bundle.removals()}
1123-
assert can_replace(existing_items, removals, new_item) == expected
1125+
assert can_replace(existing_items, new_item) == expected
11241126

11251127

11261128
@pytest.mark.anyio
@@ -1802,16 +1804,16 @@ async def test_bundle_coin_spends() -> None:
18021804
assert mi123e.bundle_coin_spends[coins[i].name()] == BundleCoinSpend(
18031805
coin_spend=sb123.coin_spends[i],
18041806
eligible_for_dedup=False,
1805-
eligible_for_fast_forward=False,
18061807
additions=[Coin(coins[i].name(), IDENTITY_PUZZLE_HASH, coins[i].amount)],
18071808
cost=uint64(ConditionCost.CREATE_COIN.value + ConditionCost.AGG_SIG.value + execution_cost),
1809+
latest_singleton_lineage=None,
18081810
)
18091811
assert mi123e.bundle_coin_spends[coins[3].name()] == BundleCoinSpend(
18101812
coin_spend=eligible_sb.coin_spends[0],
18111813
eligible_for_dedup=True,
1812-
eligible_for_fast_forward=False,
18131814
additions=[Coin(coins[3].name(), IDENTITY_PUZZLE_HASH, coins[3].amount)],
18141815
cost=uint64(ConditionCost.CREATE_COIN.value + execution_cost),
1816+
latest_singleton_lineage=None,
18151817
)
18161818

18171819

@@ -2463,7 +2465,7 @@ async def test_new_peak_ff_eviction(
24632465
item = mempool_manager.get_mempool_item(bundle.name())
24642466
assert item is not None
24652467
singleton_name = singleton_spend.coin.name()
2466-
assert item.bundle_coin_spends[singleton_name].eligible_for_fast_forward
2468+
assert item.bundle_coin_spends[singleton_name].supports_fast_forward
24672469
latest_singleton_lineage = item.bundle_coin_spends[singleton_name].latest_singleton_lineage
24682470
assert latest_singleton_lineage is not None
24692471
assert latest_singleton_lineage.coin_id == singleton_name
@@ -2495,7 +2497,7 @@ async def test_new_peak_ff_eviction(
24952497
else:
24962498
item = mempool_manager.get_mempool_item(bundle.name())
24972499
assert item is not None
2498-
assert item.bundle_coin_spends[singleton_spend.coin.name()].eligible_for_fast_forward
2500+
assert item.bundle_coin_spends[singleton_spend.coin.name()].supports_fast_forward
24992501
latest_singleton_lineage = item.bundle_coin_spends[singleton_spend.coin.name()].latest_singleton_lineage
25002502
assert latest_singleton_lineage is not None
25012503
assert latest_singleton_lineage.coin_id == singleton_spend.coin.name()
@@ -2552,9 +2554,9 @@ async def test_multiple_ff(use_optimization: bool) -> None:
25522554

25532555
item = mempool_manager.get_mempool_item(bundle.name())
25542556
assert item is not None
2555-
assert item.bundle_coin_spends[singleton_spend1.coin.name()].eligible_for_fast_forward
2556-
assert item.bundle_coin_spends[singleton_spend2.coin.name()].eligible_for_fast_forward
2557-
assert not item.bundle_coin_spends[coin_spend.coin.name()].eligible_for_fast_forward
2557+
assert item.bundle_coin_spends[singleton_spend1.coin.name()].supports_fast_forward
2558+
assert item.bundle_coin_spends[singleton_spend2.coin.name()].supports_fast_forward
2559+
assert not item.bundle_coin_spends[coin_spend.coin.name()].supports_fast_forward
25582560

25592561
# spend the singleton coin2 and make coin3 the latest version
25602562
coins.update_lineage(singleton_ph, singleton_spend3.coin)
@@ -2616,7 +2618,7 @@ async def test_advancing_ff(use_optimization: bool) -> None:
26162618
item = mempool_manager.get_mempool_item(bundle.name())
26172619
assert item is not None
26182620
spend = item.bundle_coin_spends[spend_a.coin.name()]
2619-
assert spend.eligible_for_fast_forward
2621+
assert spend.supports_fast_forward
26202622
assert spend.latest_singleton_lineage is not None
26212623
assert spend.latest_singleton_lineage.coin_id == spend_a.coin.name()
26222624

@@ -2628,7 +2630,7 @@ async def test_advancing_ff(use_optimization: bool) -> None:
26282630
item = mempool_manager.get_mempool_item(bundle.name())
26292631
assert item is not None
26302632
spend = item.bundle_coin_spends[spend_a.coin.name()]
2631-
assert spend.eligible_for_fast_forward
2633+
assert spend.supports_fast_forward
26322634
assert spend.latest_singleton_lineage is not None
26332635
assert spend.latest_singleton_lineage.coin_id == spend_b.coin.name()
26342636

@@ -2640,7 +2642,7 @@ async def test_advancing_ff(use_optimization: bool) -> None:
26402642
item = mempool_manager.get_mempool_item(bundle.name())
26412643
assert item is not None
26422644
spend = item.bundle_coin_spends[spend_a.coin.name()]
2643-
assert spend.eligible_for_fast_forward
2645+
assert spend.supports_fast_forward
26442646
assert spend.latest_singleton_lineage is not None
26452647
assert spend.latest_singleton_lineage.coin_id == spend_c.coin.name()
26462648

chia/_tests/core/mempool/test_singleton_fast_forward.py

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def test_process_fast_forward_spends_nothing_to_do() -> None:
5252
sb = spend_bundle_from_conditions(conditions, TEST_COIN, sig)
5353
item = mempool_item_from_spendbundle(sb)
5454
# This coin is not eligible for fast forward
55-
assert item.bundle_coin_spends[TEST_COIN_ID].eligible_for_fast_forward is False
55+
assert not item.bundle_coin_spends[TEST_COIN_ID].supports_fast_forward
5656
internal_mempool_item = InternalMempoolItem(sb, item.conds, item.height_added_to_mempool, item.bundle_coin_spends)
5757
original_version = dataclasses.replace(internal_mempool_item)
5858
singleton_ff = SingletonFastForward()
@@ -63,28 +63,6 @@ def test_process_fast_forward_spends_nothing_to_do() -> None:
6363
assert bundle_coin_spends == original_version.bundle_coin_spends
6464

6565

66-
def test_process_fast_forward_spends_unknown_ff() -> None:
67-
"""
68-
This tests the case when we process for the first time but we are unable
69-
to lookup the latest version from the item's latest singleton lineage
70-
"""
71-
test_coin = Coin(TEST_COIN_ID, IDENTITY_PUZZLE_HASH, uint64(1))
72-
conditions = [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 1]]
73-
sb = spend_bundle_from_conditions(conditions, test_coin)
74-
item = mempool_item_from_spendbundle(sb)
75-
# The coin is eligible for fast forward
76-
assert item.bundle_coin_spends[test_coin.name()].eligible_for_fast_forward is True
77-
item.bundle_coin_spends[test_coin.name()].latest_singleton_lineage = None
78-
internal_mempool_item = InternalMempoolItem(sb, item.conds, item.height_added_to_mempool, item.bundle_coin_spends)
79-
singleton_ff = SingletonFastForward()
80-
# We have no fast forward records yet, so we'll process this coin for the
81-
# first time here, but the item's latest singleton lineage returns None
82-
with pytest.raises(ValueError, match="Cannot proceed with singleton spend fast forward"):
83-
singleton_ff.process_fast_forward_spends(
84-
mempool_item=internal_mempool_item, height=TEST_HEIGHT, constants=DEFAULT_CONSTANTS
85-
)
86-
87-
8866
def test_process_fast_forward_spends_latest_unspent() -> None:
8967
"""
9068
This tests the case when we are the latest singleton version already, so
@@ -103,7 +81,7 @@ def test_process_fast_forward_spends_latest_unspent() -> None:
10381
conditions = [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, test_amount]]
10482
sb = spend_bundle_from_conditions(conditions, test_coin)
10583
item = mempool_item_from_spendbundle(sb)
106-
assert item.bundle_coin_spends[test_coin.name()].eligible_for_fast_forward is True
84+
assert item.bundle_coin_spends[test_coin.name()].supports_fast_forward
10785
item.bundle_coin_spends[test_coin.name()].latest_singleton_lineage = test_unspent_lineage_info
10886
internal_mempool_item = InternalMempoolItem(sb, item.conds, item.height_added_to_mempool, item.bundle_coin_spends)
10987
original_version = dataclasses.replace(internal_mempool_item)
@@ -168,12 +146,12 @@ def test_perform_the_fast_forward() -> None:
168146
"517b0dadb0c310ded24dd86dff8205398080ff808080"
169147
)
170148
test_coin_spend = CoinSpend(test_coin, test_puzzle_reveal, test_solution)
171-
test_spend_data = BundleCoinSpend(test_coin_spend, False, True, [test_child_coin], uint64(0))
172149
test_unspent_lineage_info = UnspentLineageInfo(
173150
coin_id=latest_unspent_coin.name(),
174151
parent_id=latest_unspent_coin.parent_coin_info,
175152
parent_parent_id=test_child_coin.parent_coin_info,
176153
)
154+
test_spend_data = BundleCoinSpend(test_coin_spend, False, [test_child_coin], uint64(0), test_unspent_lineage_info)
177155
# Start from a fresh state of fast forward spends
178156
fast_forward_spends: dict[bytes32, UnspentLineageInfo] = {}
179157
# Perform the fast forward on the test coin (the grandparent)

chia/_tests/core/util/test_lru_cache.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import unittest
44

5+
import pytest
6+
57
from chia.util.lru_cache import LRUCache
68

79

@@ -54,3 +56,17 @@ def test_lru_cache(self):
5456
assert len(cache.cache) == 5
5557
assert cache.get(b"0") is None
5658
assert cache.get(b"1") == 1
59+
60+
61+
@pytest.mark.parametrize(argnames="capacity", argvalues=[-10, -1, 0])
62+
def test_with_zero_capacity(capacity: int) -> None:
63+
cache: LRUCache[bytes, int] = LRUCache(capacity=capacity)
64+
cache.put(b"0", 1)
65+
assert cache.get(b"0") is None
66+
assert len(cache.cache) == 0
67+
68+
69+
@pytest.mark.parametrize(argnames="capacity", argvalues=[-10, -1, 0, 1, 5, 10])
70+
def test_get_capacity(capacity: int) -> None:
71+
cache: LRUCache[object, object] = LRUCache(capacity=capacity)
72+
assert cache.get_capacity() == capacity

chia/_tests/wallet/rpc/test_wallet_rpc.py

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
PushTX,
145145
RoyaltyAsset,
146146
SelectCoins,
147+
SendNotification,
147148
SendTransaction,
148149
SetWalletResyncOnStartup,
149150
SpendClawbackCoins,
@@ -2621,21 +2622,25 @@ async def test_notification_rpcs(wallet_rpc_environment: WalletRpcTestEnvironmen
26212622
env.wallet_2.node.config["enable_notifications"] = True
26222623
env.wallet_2.node.config["required_notification_amount"] = 100000000000
26232624
async with wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
2624-
tx = await client.send_notification(
2625-
await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager),
2626-
b"hello",
2627-
uint64(100000000000),
2628-
fee=uint64(100000000000),
2625+
response = await client.send_notification(
2626+
SendNotification(
2627+
target=(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager)),
2628+
message=b"hello",
2629+
amount=uint64(100000000000),
2630+
fee=uint64(100000000000),
2631+
push=True,
2632+
),
2633+
tx_config=DEFAULT_TX_CONFIG,
26292634
)
26302635

2631-
assert tx.spend_bundle is not None
2636+
assert response.tx.spend_bundle is not None
26322637
await time_out_assert(
26332638
5,
26342639
full_node_api.full_node.mempool_manager.get_spendbundle,
2635-
tx.spend_bundle,
2636-
tx.spend_bundle.name(),
2640+
response.tx.spend_bundle,
2641+
response.tx.spend_bundle.name(),
26372642
)
2638-
await farm_transaction(full_node_api, wallet_node, tx.spend_bundle)
2643+
await farm_transaction(full_node_api, wallet_node, response.tx.spend_bundle)
26392644
await time_out_assert(20, env.wallet_2.wallet.get_confirmed_balance, uint64(100000000000))
26402645

26412646
notification = (await client_2.get_notifications(GetNotifications())).notifications[0]
@@ -2648,21 +2653,25 @@ async def test_notification_rpcs(wallet_rpc_environment: WalletRpcTestEnvironmen
26482653
assert [] == (await client_2.get_notifications(GetNotifications([notification.id]))).notifications
26492654

26502655
async with wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
2651-
tx = await client.send_notification(
2652-
await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager),
2653-
b"hello",
2654-
uint64(100000000000),
2655-
fee=uint64(100000000000),
2656+
response = await client.send_notification(
2657+
SendNotification(
2658+
target=(await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager)),
2659+
message=b"hello",
2660+
amount=uint64(100000000000),
2661+
fee=uint64(100000000000),
2662+
push=True,
2663+
),
2664+
tx_config=DEFAULT_TX_CONFIG,
26562665
)
26572666

2658-
assert tx.spend_bundle is not None
2667+
assert response.tx.spend_bundle is not None
26592668
await time_out_assert(
26602669
5,
26612670
full_node_api.full_node.mempool_manager.get_spendbundle,
2662-
tx.spend_bundle,
2663-
tx.spend_bundle.name(),
2671+
response.tx.spend_bundle,
2672+
response.tx.spend_bundle.name(),
26642673
)
2665-
await farm_transaction(full_node_api, wallet_node, tx.spend_bundle)
2674+
await farm_transaction(full_node_api, wallet_node, response.tx.spend_bundle)
26662675
await time_out_assert(20, env.wallet_2.wallet.get_confirmed_balance, uint64(200000000000))
26672676

26682677
notification = (await client_2.get_notifications(GetNotifications())).notifications[0]

chia/cmds/wallet_funcs.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
NFTSetNFTDID,
7575
NFTTransferNFT,
7676
RoyaltyAsset,
77+
SendNotification,
7778
SendTransaction,
7879
SendTransactionResponse,
7980
SignMessageByAddress,
@@ -1576,19 +1577,25 @@ async def send_notification(
15761577
async with get_wallet_client(root_path, wallet_rpc_port, fp) as (wallet_client, fingerprint, _):
15771578
amount: uint64 = cli_amount.convert_amount(units["chia"])
15781579

1579-
tx = await wallet_client.send_notification(
1580-
address.puzzle_hash,
1581-
message,
1582-
amount,
1583-
fee,
1584-
push=push,
1580+
response = await wallet_client.send_notification(
1581+
SendNotification(
1582+
address.puzzle_hash,
1583+
message,
1584+
amount,
1585+
fee=fee,
1586+
push=push,
1587+
),
1588+
tx_config=DEFAULT_TX_CONFIG,
15851589
timelock_info=condition_valid_times,
15861590
)
15871591

15881592
if push:
15891593
print("Notification sent successfully.")
1590-
print(f"To get status, use command: chia wallet get_transaction -f {fingerprint} -tx 0x{tx.name}")
1591-
return [tx]
1594+
print(
1595+
"To get status, use command: chia wallet get_transaction"
1596+
f" -f {fingerprint} -tx 0x{response.transactions[0].name}"
1597+
)
1598+
return response.transactions
15921599

15931600

15941601
async def get_notifications(

0 commit comments

Comments
 (0)