mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-11-10 12:29:49 +03:00
move member function get_memos() out of SpendBundle and into a free-function living in the wallet code. It does not belong to the full node. Also rename it to indicate that it's expensive (and dangerous) to call (#9907)
This commit is contained in:
parent
5f4e39480e
commit
77db90ba6a
@ -2,20 +2,17 @@ import dataclasses
|
||||
import warnings
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Dict
|
||||
from typing import List
|
||||
|
||||
from blspy import AugSchemeMPL, G2Element
|
||||
from clvm.casts import int_from_bytes
|
||||
|
||||
from chia.consensus.default_constants import DEFAULT_CONSTANTS
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.util.streamable import Streamable, dataclass_from_dict, recurse_jsonify, streamable
|
||||
from chia.wallet.util.debug_spend_bundle import debug_spend_bundle
|
||||
from .blockchain_format.program import Program
|
||||
|
||||
from .coin_spend import CoinSpend
|
||||
from .condition_opcodes import ConditionOpcode
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@ -80,27 +77,6 @@ class SpendBundle(Streamable):
|
||||
|
||||
return result
|
||||
|
||||
def get_memos(self) -> Dict[bytes32, List[bytes]]:
|
||||
"""
|
||||
Retrieves the memos for additions in this spend_bundle, which are formatted as a list in the 3rd parameter of
|
||||
CREATE_COIN. If there are no memos, the addition coin_id is not included. If they are not formatted as a list
|
||||
of bytes, they are not included. This is expensive to call, it should not be used in full node code.
|
||||
"""
|
||||
memos: Dict[bytes32, List[bytes]] = {}
|
||||
for coin_spend in self.coin_spends:
|
||||
result = Program.from_bytes(bytes(coin_spend.puzzle_reveal)).run(
|
||||
Program.from_bytes(bytes(coin_spend.solution))
|
||||
)
|
||||
for condition in result.as_python():
|
||||
if condition[0] == ConditionOpcode.CREATE_COIN and len(condition) >= 4:
|
||||
# If only 3 elements (opcode + 2 args), there is no memo, this is ph, amount
|
||||
coin_added = Coin(coin_spend.coin.name(), bytes32(condition[1]), int_from_bytes(condition[2]))
|
||||
if type(condition[3]) != list:
|
||||
# If it's not a list, it's not the correct format
|
||||
continue
|
||||
memos[coin_added.name()] = condition[3]
|
||||
return memos
|
||||
|
||||
# Note that `coin_spends` used to have the bad name `coin_solutions`.
|
||||
# Some API still expects this name. For now, we accept both names.
|
||||
#
|
||||
|
@ -46,6 +46,7 @@ from chia.wallet.util.wallet_types import WalletType, AmountWithPuzzlehash
|
||||
from chia.wallet.wallet import Wallet
|
||||
from chia.wallet.wallet_coin_record import WalletCoinRecord
|
||||
from chia.wallet.wallet_info import WalletInfo
|
||||
from chia.wallet.util.compute_memos import compute_memos
|
||||
|
||||
|
||||
# This should probably not live in this file but it's for experimental right now
|
||||
@ -720,7 +721,7 @@ class CATWallet:
|
||||
trade_id=None,
|
||||
type=uint32(TransactionType.OUTGOING_TX.value),
|
||||
name=spend_bundle.name(),
|
||||
memos=list(spend_bundle.get_memos().items()),
|
||||
memos=list(compute_memos(spend_bundle).items()),
|
||||
)
|
||||
]
|
||||
|
||||
|
@ -20,6 +20,7 @@ from chia.wallet.did_wallet.did_info import DIDInfo
|
||||
from chia.wallet.lineage_proof import LineageProof
|
||||
from chia.wallet.transaction_record import TransactionRecord
|
||||
from chia.wallet.util.wallet_types import WalletType
|
||||
from chia.wallet.util.compute_memos import compute_memos
|
||||
from chia.wallet.wallet import Wallet
|
||||
from chia.wallet.wallet_coin_record import WalletCoinRecord
|
||||
from chia.wallet.wallet_info import WalletInfo
|
||||
@ -129,7 +130,7 @@ class DIDWallet:
|
||||
trade_id=None,
|
||||
type=uint32(TransactionType.OUTGOING_TX.value),
|
||||
name=bytes32(token_bytes()),
|
||||
memos=list(spend_bundle.get_memos().items()),
|
||||
memos=list(compute_memos(spend_bundle).items()),
|
||||
)
|
||||
await self.standard_wallet.push_transaction(regular_record)
|
||||
await self.standard_wallet.push_transaction(did_record)
|
||||
@ -513,7 +514,7 @@ class DIDWallet:
|
||||
trade_id=None,
|
||||
type=uint32(TransactionType.OUTGOING_TX.value),
|
||||
name=token_bytes(),
|
||||
memos=list(spend_bundle.get_memos().items()),
|
||||
memos=list(compute_memos(spend_bundle).items()),
|
||||
)
|
||||
await self.standard_wallet.push_transaction(did_record)
|
||||
return spend_bundle
|
||||
@ -582,7 +583,7 @@ class DIDWallet:
|
||||
trade_id=None,
|
||||
type=uint32(TransactionType.OUTGOING_TX.value),
|
||||
name=bytes32(token_bytes()),
|
||||
memos=list(spend_bundle.get_memos().items()),
|
||||
memos=list(compute_memos(spend_bundle).items()),
|
||||
)
|
||||
await self.standard_wallet.push_transaction(did_record)
|
||||
return spend_bundle
|
||||
@ -649,7 +650,7 @@ class DIDWallet:
|
||||
trade_id=None,
|
||||
type=uint32(TransactionType.OUTGOING_TX.value),
|
||||
name=bytes32(token_bytes()),
|
||||
memos=list(spend_bundle.get_memos().items()),
|
||||
memos=list(compute_memos(spend_bundle).items()),
|
||||
)
|
||||
await self.standard_wallet.push_transaction(did_record)
|
||||
return spend_bundle
|
||||
@ -718,7 +719,7 @@ class DIDWallet:
|
||||
trade_id=None,
|
||||
type=uint32(TransactionType.INCOMING_TX.value),
|
||||
name=bytes32(token_bytes()),
|
||||
memos=list(spend_bundle.get_memos().items()),
|
||||
memos=list(compute_memos(spend_bundle).items()),
|
||||
)
|
||||
await self.standard_wallet.push_transaction(did_record)
|
||||
if filename is not None:
|
||||
@ -859,7 +860,7 @@ class DIDWallet:
|
||||
trade_id=None,
|
||||
type=uint32(TransactionType.OUTGOING_TX.value),
|
||||
name=bytes32(token_bytes()),
|
||||
memos=list(spend_bundle.get_memos().items()),
|
||||
memos=list(compute_memos(spend_bundle).items()),
|
||||
)
|
||||
await self.standard_wallet.push_transaction(did_record)
|
||||
new_did_info = DIDInfo(
|
||||
|
@ -29,6 +29,7 @@ from chia.wallet.rl_wallet.rl_wallet_puzzles import (
|
||||
from chia.wallet.transaction_record import TransactionRecord
|
||||
from chia.wallet.util.transaction_type import TransactionType
|
||||
from chia.wallet.util.wallet_types import WalletType
|
||||
from chia.wallet.util.compute_memos import compute_memos
|
||||
from chia.wallet.wallet import Wallet
|
||||
from chia.wallet.wallet_coin_record import WalletCoinRecord
|
||||
from chia.wallet.wallet_info import WalletInfo
|
||||
@ -320,7 +321,7 @@ class RLWallet:
|
||||
trade_id=None,
|
||||
type=uint32(TransactionType.OUTGOING_TX.value),
|
||||
name=spend_bundle.name(),
|
||||
memos=list(spend_bundle.get_memos().items()),
|
||||
memos=list(compute_memos(spend_bundle).items()),
|
||||
)
|
||||
|
||||
asyncio.create_task(self.push_transaction(tx_record))
|
||||
@ -546,7 +547,7 @@ class RLWallet:
|
||||
trade_id=None,
|
||||
type=uint32(TransactionType.OUTGOING_TX.value),
|
||||
name=spend_bundle.name(),
|
||||
memos=list(spend_bundle.get_memos().items()),
|
||||
memos=list(compute_memos(spend_bundle).items()),
|
||||
)
|
||||
|
||||
async def rl_sign_transaction(self, spends: List[CoinSpend]) -> SpendBundle:
|
||||
@ -623,7 +624,7 @@ class RLWallet:
|
||||
trade_id=None,
|
||||
type=uint32(TransactionType.OUTGOING_TX.value),
|
||||
name=spend_bundle.name(),
|
||||
memos=list(spend_bundle.get_memos().items()),
|
||||
memos=list(compute_memos(spend_bundle).items()),
|
||||
)
|
||||
|
||||
# This is for using the AC locked coin and aggregating it into wallet - must happen in same block as RL Mode 2
|
||||
|
28
chia/wallet/util/compute_memos.py
Normal file
28
chia/wallet/util/compute_memos.py
Normal file
@ -0,0 +1,28 @@
|
||||
from typing import List, Dict
|
||||
|
||||
from clvm.casts import int_from_bytes
|
||||
from chia.types.blockchain_format.program import Program
|
||||
from chia.types.spend_bundle import SpendBundle
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.condition_opcodes import ConditionOpcode
|
||||
|
||||
|
||||
def compute_memos(bundle: SpendBundle) -> Dict[bytes32, List[bytes]]:
|
||||
"""
|
||||
Retrieves the memos for additions in this spend_bundle, which are formatted as a list in the 3rd parameter of
|
||||
CREATE_COIN. If there are no memos, the addition coin_id is not included. If they are not formatted as a list
|
||||
of bytes, they are not included. This is expensive to call, it should not be used in full node code.
|
||||
"""
|
||||
memos: Dict[bytes32, List[bytes]] = {}
|
||||
for coin_spend in bundle.coin_spends:
|
||||
result = Program.from_bytes(bytes(coin_spend.puzzle_reveal)).run(Program.from_bytes(bytes(coin_spend.solution)))
|
||||
for condition in result.as_python():
|
||||
if condition[0] == ConditionOpcode.CREATE_COIN and len(condition) >= 4:
|
||||
# If only 3 elements (opcode + 2 args), there is no memo, this is ph, amount
|
||||
coin_added = Coin(coin_spend.coin.name(), bytes32(condition[1]), int_from_bytes(condition[2]))
|
||||
if type(condition[3]) != list:
|
||||
# If it's not a list, it's not the correct format
|
||||
continue
|
||||
memos[coin_added.name()] = condition[3]
|
||||
return memos
|
@ -40,6 +40,7 @@ from chia.wallet.util.transaction_type import TransactionType
|
||||
from chia.wallet.util.wallet_types import WalletType, AmountWithPuzzlehash
|
||||
from chia.wallet.wallet_coin_record import WalletCoinRecord
|
||||
from chia.wallet.wallet_info import WalletInfo
|
||||
from chia.wallet.util.compute_memos import compute_memos
|
||||
|
||||
|
||||
class Wallet:
|
||||
@ -485,7 +486,7 @@ class Wallet:
|
||||
trade_id=None,
|
||||
type=uint32(TransactionType.OUTGOING_TX.value),
|
||||
name=spend_bundle.name(),
|
||||
memos=list(spend_bundle.get_memos().items()),
|
||||
memos=list(compute_memos(spend_bundle).items()),
|
||||
)
|
||||
|
||||
async def push_transaction(self, tx: TransactionRecord) -> None:
|
||||
|
@ -31,6 +31,7 @@ from chia.wallet.cat_wallet.cat_constants import DEFAULT_CATS
|
||||
from chia.wallet.trading.trade_status import TradeStatus
|
||||
from chia.wallet.transaction_record import TransactionRecord
|
||||
from chia.wallet.transaction_sorting import SortKey
|
||||
from chia.wallet.util.compute_memos import compute_memos
|
||||
from tests.setup_nodes import bt, setup_simulators_and_wallets, self_hostname
|
||||
from tests.time_out_assert import time_out_assert
|
||||
|
||||
@ -293,7 +294,7 @@ class TestWalletRpc:
|
||||
addition.parent_coin_info, cr.confirmed_block_index
|
||||
)
|
||||
sb: SpendBundle = SpendBundle([spend], G2Element())
|
||||
assert sb.get_memos() == {addition.name(): [b"hhh"]}
|
||||
assert compute_memos(sb) == {addition.name(): [b"hhh"]}
|
||||
found = True
|
||||
assert found
|
||||
|
||||
@ -364,12 +365,16 @@ class TestWalletRpc:
|
||||
# Checks that the memo can be retrieved
|
||||
tx_confirmed = await client.get_transaction("1", send_tx_res.name)
|
||||
assert tx_confirmed.confirmed
|
||||
assert len(tx_confirmed.get_memos()) == 2
|
||||
print(tx_confirmed.get_memos())
|
||||
assert [b"FiMemo"] in tx_confirmed.get_memos().values()
|
||||
assert [b"SeMemo"] in tx_confirmed.get_memos().values()
|
||||
assert list(tx_confirmed.get_memos().keys())[0] in [a.name() for a in send_tx_res.spend_bundle.additions()]
|
||||
assert list(tx_confirmed.get_memos().keys())[1] in [a.name() for a in send_tx_res.spend_bundle.additions()]
|
||||
if isinstance(tx_confirmed, SpendBundle):
|
||||
memos = compute_memos(tx_confirmed)
|
||||
else:
|
||||
memos = tx_confirmed.get_memos()
|
||||
assert len(memos) == 2
|
||||
print(memos)
|
||||
assert [b"FiMemo"] in memos.values()
|
||||
assert [b"SeMemo"] in memos.values()
|
||||
assert list(memos.keys())[0] in [a.name() for a in send_tx_res.spend_bundle.additions()]
|
||||
assert list(memos.keys())[1] in [a.name() for a in send_tx_res.spend_bundle.additions()]
|
||||
|
||||
##############
|
||||
# CATS #
|
||||
|
@ -11,6 +11,7 @@ from chia.types.peer_info import PeerInfo
|
||||
from chia.util.ints import uint16, uint32, uint64
|
||||
from chia.wallet.derive_keys import master_sk_to_wallet_sk
|
||||
from chia.wallet.util.transaction_type import TransactionType
|
||||
from chia.wallet.util.compute_memos import compute_memos
|
||||
from chia.wallet.transaction_record import TransactionRecord
|
||||
from chia.wallet.wallet_node import WalletNode
|
||||
from chia.wallet.wallet_state_manager import WalletStateManager
|
||||
@ -617,7 +618,7 @@ class TestWalletSimulator:
|
||||
trade_id=None,
|
||||
type=uint32(TransactionType.OUTGOING_TX.value),
|
||||
name=name,
|
||||
memos=list(stolen_sb.get_memos().items()),
|
||||
memos=list(compute_memos(stolen_sb).items()),
|
||||
)
|
||||
await wallet.push_transaction(stolen_tx)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user