Merge commit '3c2fc1947df311aa80130a0f60288547cf09250d' into checkpoint/long_lived_atari_from_main_3c2fc1947df311aa80130a0f60288547cf09250d
This commit is contained in:
commit
9d4a66287c
13 changed files with 45 additions and 73 deletions
|
@ -211,10 +211,10 @@ async def validate_block_body(
|
|||
assert npc_result.conds is not None
|
||||
|
||||
for spend in npc_result.conds.spends:
|
||||
removals.append(spend.coin_id)
|
||||
removals_puzzle_dic[spend.coin_id] = spend.puzzle_hash
|
||||
removals.append(bytes32(spend.coin_id))
|
||||
removals_puzzle_dic[bytes32(spend.coin_id)] = bytes32(spend.puzzle_hash)
|
||||
for puzzle_hash, amount, _ in spend.create_coin:
|
||||
c = Coin(spend.coin_id, puzzle_hash, uint64(amount))
|
||||
c = Coin(bytes32(spend.coin_id), bytes32(puzzle_hash), uint64(amount))
|
||||
additions.append((c, c.name()))
|
||||
else:
|
||||
assert npc_result is None
|
||||
|
@ -431,7 +431,7 @@ async def validate_block_body(
|
|||
assert_fee_sum: uint64 = uint64(0)
|
||||
if npc_result:
|
||||
assert npc_result.conds is not None
|
||||
assert_fee_sum = npc_result.conds.reserve_fee
|
||||
assert_fee_sum = uint64(npc_result.conds.reserve_fee)
|
||||
|
||||
# 17. Check that the assert fee sum <= fees, and that each reserved fee is non-negative
|
||||
if fees < assert_fee_sum:
|
||||
|
|
|
@ -3,6 +3,7 @@ from typing import Dict, List, Optional, Set, Tuple
|
|||
from chia.consensus.blockchain import StateChangeSummary
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.util.ints import uint64
|
||||
|
||||
|
||||
def get_hints_and_subscription_coin_ids(
|
||||
|
@ -32,11 +33,11 @@ def get_hints_and_subscription_coin_ids(
|
|||
if npc_result.conds is not None:
|
||||
for spend in npc_result.conds.spends:
|
||||
# Record all coin_ids that we are interested in, that had changes
|
||||
add_if_coin_subscription(spend.coin_id)
|
||||
add_if_ph_subscription(spend.puzzle_hash, spend.coin_id)
|
||||
add_if_coin_subscription(bytes32(spend.coin_id))
|
||||
add_if_ph_subscription(bytes32(spend.puzzle_hash), bytes32(spend.coin_id))
|
||||
|
||||
for new_ph, new_am, hint in spend.create_coin:
|
||||
addition_coin: Coin = Coin(spend.coin_id, new_ph, new_am)
|
||||
addition_coin: Coin = Coin(bytes32(spend.coin_id), bytes32(new_ph), uint64(new_am))
|
||||
addition_coin_name = addition_coin.name()
|
||||
add_if_coin_subscription(addition_coin_name)
|
||||
add_if_ph_subscription(addition_coin.puzzle_hash, addition_coin_name)
|
||||
|
|
|
@ -94,7 +94,7 @@ def mempool_check_time_locks(
|
|||
return Err.ASSERT_SECONDS_ABSOLUTE_FAILED
|
||||
|
||||
for spend in bundle_conds.spends:
|
||||
unspent = removal_coin_records[spend.coin_id]
|
||||
unspent = removal_coin_records[bytes32(spend.coin_id)]
|
||||
if spend.height_relative is not None:
|
||||
if prev_transaction_block_height < unspent.confirmed_block_index + spend.height_relative:
|
||||
return Err.ASSERT_HEIGHT_RELATIVE_FAILED
|
||||
|
|
|
@ -314,7 +314,7 @@ class MempoolManager:
|
|||
|
||||
assert npc_result.conds is not None
|
||||
# build removal list
|
||||
removal_names: List[bytes32] = [spend.coin_id for spend in npc_result.conds.spends]
|
||||
removal_names: List[bytes32] = [bytes32(spend.coin_id) for spend in npc_result.conds.spends]
|
||||
if set(removal_names) != set([s.name() for s in new_spend.removals()]):
|
||||
# If you reach here it's probably because your program reveal doesn't match the coin's puzzle hash
|
||||
return None, MempoolInclusionStatus.FAILED, Err.INVALID_SPEND_BUNDLE
|
||||
|
@ -432,11 +432,11 @@ class MempoolManager:
|
|||
|
||||
# Verify conditions, create hash_key list for aggsig check
|
||||
for spend in npc_result.conds.spends:
|
||||
coin_record: CoinRecord = removal_record_dict[spend.coin_id]
|
||||
coin_record: CoinRecord = removal_record_dict[bytes32(spend.coin_id)]
|
||||
# Check that the revealed removal puzzles actually match the puzzle hash
|
||||
if spend.puzzle_hash != coin_record.coin.puzzle_hash:
|
||||
log.warning("Mempool rejecting transaction because of wrong puzzle_hash")
|
||||
log.warning(f"{spend.puzzle_hash} != {coin_record.coin.puzzle_hash}")
|
||||
log.warning(f"{spend.puzzle_hash.hex()} != {coin_record.coin.puzzle_hash.hex()}")
|
||||
return None, MempoolInclusionStatus.FAILED, Err.WRONG_PUZZLE_HASH
|
||||
|
||||
chialisp_height = (
|
||||
|
@ -536,7 +536,7 @@ class MempoolManager:
|
|||
if last_npc_result.conds is not None:
|
||||
for spend in last_npc_result.conds.spends:
|
||||
if spend.coin_id in self.mempool.removals:
|
||||
item = self.mempool.removals[spend.coin_id]
|
||||
item = self.mempool.removals[bytes32(spend.coin_id)]
|
||||
self.mempool.remove_from_pool(item)
|
||||
self.remove_seen(item.spend_bundle_name)
|
||||
else:
|
||||
|
|
|
@ -11,7 +11,7 @@ from clvm_tools.curry import uncurry
|
|||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.util.hash import std_hash
|
||||
from chia.util.byte_types import hexstr_to_bytes
|
||||
from chia.types.spend_bundle_conditions import SpendBundleConditions, Spend
|
||||
from chia.types.spend_bundle_conditions import SpendBundleConditions
|
||||
|
||||
from .tree_hash import sha256_treehash
|
||||
|
||||
|
@ -256,7 +256,7 @@ class SerializedProgram:
|
|||
else:
|
||||
serialized_args += _serialize(args[0])
|
||||
|
||||
err, conds = run_generator(
|
||||
err, ret = run_generator(
|
||||
self._buf,
|
||||
serialized_args,
|
||||
max_cost,
|
||||
|
@ -266,22 +266,6 @@ class SerializedProgram:
|
|||
assert err != 0
|
||||
return err, None
|
||||
|
||||
# for now, we need to copy this data into python objects, in order to
|
||||
# support streamable. This will become simpler and faster once we can
|
||||
# implement streamable in rust
|
||||
spends = []
|
||||
for s in conds.spends:
|
||||
create_coins = []
|
||||
for ph, amount, hint in s.create_coin:
|
||||
create_coins.append((ph, amount, None if hint == b"" else hint))
|
||||
spends.append(
|
||||
Spend(s.coin_id, s.puzzle_hash, s.height_relative, s.seconds_relative, create_coins, s.agg_sig_me)
|
||||
)
|
||||
|
||||
ret = SpendBundleConditions(
|
||||
spends, conds.reserve_fee, conds.height_absolute, conds.seconds_absolute, conds.agg_sig_unsafe, conds.cost
|
||||
)
|
||||
|
||||
assert ret is not None
|
||||
return None, ret
|
||||
|
||||
|
|
|
@ -1,30 +1,3 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import List, Optional, Tuple
|
||||
from chia_rs import Spend, SpendBundleConditions
|
||||
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32, bytes48
|
||||
from chia.util.ints import uint32, uint64
|
||||
from chia.util.streamable import Streamable, streamable
|
||||
|
||||
|
||||
# the Spend and SpendBundleConditions classes are mirrors of native types, returned by
|
||||
# run_generator
|
||||
@streamable
|
||||
@dataclass(frozen=True)
|
||||
class Spend(Streamable):
|
||||
coin_id: bytes32
|
||||
puzzle_hash: bytes32
|
||||
height_relative: Optional[uint32]
|
||||
seconds_relative: uint64
|
||||
create_coin: List[Tuple[bytes32, uint64, Optional[bytes]]]
|
||||
agg_sig_me: List[Tuple[bytes48, bytes]]
|
||||
|
||||
|
||||
@streamable
|
||||
@dataclass(frozen=True)
|
||||
class SpendBundleConditions(Streamable):
|
||||
spends: List[Spend]
|
||||
reserve_fee: uint64
|
||||
height_absolute: uint32
|
||||
seconds_absolute: uint64
|
||||
agg_sig_unsafe: List[Tuple[bytes48, bytes]]
|
||||
cost: uint64
|
||||
__all__ = ["Spend", "SpendBundleConditions"]
|
||||
|
|
|
@ -45,7 +45,7 @@ def additions_for_npc(npc_result: NPCResult) -> List[Coin]:
|
|||
return []
|
||||
for spend in npc_result.conds.spends:
|
||||
for puzzle_hash, amount, _ in spend.create_coin:
|
||||
coin = Coin(spend.coin_id, puzzle_hash, uint64(amount))
|
||||
coin = Coin(bytes32(spend.coin_id), bytes32(puzzle_hash), uint64(amount))
|
||||
additions.append(coin)
|
||||
|
||||
return additions
|
||||
|
@ -63,9 +63,9 @@ def tx_removals_and_additions(results: Optional[SpendBundleConditions]) -> Tuple
|
|||
if results is None:
|
||||
return [], []
|
||||
for spend in results.spends:
|
||||
removals.append(spend.coin_id)
|
||||
removals.append(bytes32(spend.coin_id))
|
||||
for puzzle_hash, amount, _ in spend.create_coin:
|
||||
additions.append(Coin(spend.coin_id, puzzle_hash, uint64(amount)))
|
||||
additions.append(Coin(bytes32(spend.coin_id), bytes32(puzzle_hash), uint64(amount)))
|
||||
|
||||
return removals, additions
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
|||
|
||||
import dataclasses
|
||||
import io
|
||||
import os
|
||||
import pprint
|
||||
from enum import Enum
|
||||
from typing import Any, BinaryIO, Callable, Dict, Iterator, List, Optional, Tuple, Type, TypeVar, Union, get_type_hints
|
||||
|
@ -203,6 +204,9 @@ def recurse_jsonify(d: Any) -> Any:
|
|||
return int(d)
|
||||
elif d is None or type(d) == str:
|
||||
return d
|
||||
elif hasattr(d, "to_json_dict"):
|
||||
ret: Union[List[Any], Dict[str, Any], str, None, int] = d.to_json_dict()
|
||||
return ret
|
||||
raise ValueError(f"failed to jsonify {d} (type: {type(d)})")
|
||||
|
||||
|
||||
|
@ -238,6 +242,14 @@ def parse_optional(f: BinaryIO, parse_inner_type_f: ParseFunctionType) -> Option
|
|||
raise ValueError("Optional must be 0 or 1")
|
||||
|
||||
|
||||
def parse_rust(f: BinaryIO, f_type: Type[Any]) -> Any:
|
||||
assert isinstance(f, io.BytesIO)
|
||||
buf = f.getbuffer()
|
||||
ret, advance = f_type.parse_rust(bytes(buf[f.tell() :]))
|
||||
f.seek(advance, os.SEEK_CUR)
|
||||
return ret
|
||||
|
||||
|
||||
def parse_bytes(f: BinaryIO) -> bytes:
|
||||
list_size = parse_uint32(f)
|
||||
bytes_read = f.read(list_size)
|
||||
|
@ -494,6 +506,8 @@ class Streamable:
|
|||
inner_type = get_args(f_type)[0]
|
||||
parse_inner_type_f = cls.function_to_parse_one_item(inner_type)
|
||||
return lambda f: parse_optional(f, parse_inner_type_f)
|
||||
if hasattr(f_type, "parse_rust"):
|
||||
return lambda f: parse_rust(f, f_type)
|
||||
if hasattr(f_type, "parse"):
|
||||
# Ignoring for now as the proper solution isn't obvious
|
||||
return f_type.parse # type: ignore[no-any-return]
|
||||
|
|
2
setup.py
2
setup.py
|
@ -8,7 +8,7 @@ dependencies = [
|
|||
"chiapos==1.0.10", # proof of space
|
||||
"clvm==0.9.7",
|
||||
"clvm_tools==0.4.4", # Currying, Program.to, other conveniences
|
||||
"chia_rs==0.1.2",
|
||||
"chia_rs==0.1.4",
|
||||
"clvm-tools-rs==0.1.9", # Rust implementation of clvm_tools
|
||||
"aiohttp==3.8.1", # HTTP server for full node rpc
|
||||
"aiosqlite==0.17.0", # asyncio wrapper for sqlite, to store blocks
|
||||
|
|
|
@ -73,7 +73,7 @@ class CoinStore:
|
|||
assert result.conds is not None
|
||||
for spend in result.conds.spends:
|
||||
for puzzle_hash, amount, hint in spend.create_coin:
|
||||
coin = Coin(spend.coin_id, puzzle_hash, amount)
|
||||
coin = Coin(bytes32(spend.coin_id), bytes32(puzzle_hash), uint64(amount))
|
||||
name = coin.name()
|
||||
ephemeral_db[name] = CoinRecord(
|
||||
coin,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from typing import List
|
||||
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
||||
from chia.types.spend_bundle_conditions import Spend, SpendBundleConditions
|
||||
from chia.util.generator_tools import tx_removals_and_additions
|
||||
from chia.util.hash import std_hash
|
||||
|
@ -42,7 +43,7 @@ def test_tx_removals_and_additions() -> None:
|
|||
expected_additions = []
|
||||
for spend in spends:
|
||||
for puzzle_hash, am, _ in spend.create_coin:
|
||||
expected_additions.append(Coin(spend.coin_id, puzzle_hash, am))
|
||||
expected_additions.append(Coin(bytes32(spend.coin_id), bytes32(puzzle_hash), uint64(am)))
|
||||
rems, adds = tx_removals_and_additions(conditions)
|
||||
assert rems == expected_rems
|
||||
assert adds == expected_additions
|
||||
|
|
|
@ -68,9 +68,9 @@ async def test_hints_to_add(bt: BlockTools, empty_blockchain: Blockchain) -> Non
|
|||
hints_to_add, lookup_coin_ids = get_hints_and_subscription_coin_ids(scs, {}, {})
|
||||
assert len(lookup_coin_ids) == 0
|
||||
|
||||
first_coin_id: bytes32 = Coin(spends[0].coin_id, phs[4], uint64(3)).name()
|
||||
second_coin_id: bytes32 = Coin(spends[2].coin_id, phs[6], uint64(5)).name()
|
||||
third_coin_id: bytes32 = Coin(spends[1].coin_id, phs[9], uint64(123)).name()
|
||||
first_coin_id: bytes32 = Coin(bytes32(spends[0].coin_id), bytes32(phs[4]), uint64(3)).name()
|
||||
second_coin_id: bytes32 = Coin(bytes32(spends[2].coin_id), bytes32(phs[6]), uint64(5)).name()
|
||||
third_coin_id: bytes32 = Coin(bytes32(spends[1].coin_id), bytes32(phs[9]), uint64(123)).name()
|
||||
assert set(hints_to_add) == {(first_coin_id, b"1" * 32), (second_coin_id, b"1" * 3), (third_coin_id, b"1" * 32)}
|
||||
|
||||
|
||||
|
@ -97,8 +97,8 @@ async def test_lookup_coin_ids(bt: BlockTools, empty_blockchain: Blockchain) ->
|
|||
|
||||
_, lookup_coin_ids = get_hints_and_subscription_coin_ids(scs, coin_subscriptions, ph_subscriptions)
|
||||
|
||||
first_coin_id: bytes32 = Coin(spends[0].coin_id, phs[4], uint64(3)).name()
|
||||
second_coin_id: bytes32 = Coin(spends[1].coin_id, phs[4], uint64(6)).name()
|
||||
first_coin_id: bytes32 = Coin(bytes32(spends[0].coin_id), bytes32(phs[4]), uint64(3)).name()
|
||||
second_coin_id: bytes32 = Coin(bytes32(spends[1].coin_id), bytes32(phs[4]), uint64(6)).name()
|
||||
assert set(lookup_coin_ids) == {coin_ids[1], first_coin_id, second_coin_id}
|
||||
|
||||
# Removal PH and addition ID
|
||||
|
@ -108,7 +108,7 @@ async def test_lookup_coin_ids(bt: BlockTools, empty_blockchain: Blockchain) ->
|
|||
assert set(lookup_coin_ids) == {first_coin_id, coin_ids[0], coin_ids[2]}
|
||||
|
||||
# Subscribe to hint
|
||||
third_coin_id: bytes32 = Coin(spends[1].coin_id, phs[9], uint64(123)).name()
|
||||
third_coin_id: bytes32 = Coin(bytes32(spends[1].coin_id), phs[9], uint64(123)).name()
|
||||
ph_subscriptions = {bytes32(b"1" * 32): {bytes32(b"7" * 32)}}
|
||||
_, lookup_coin_ids = get_hints_and_subscription_coin_ids(scs, {}, ph_subscriptions)
|
||||
assert set(lookup_coin_ids) == {first_coin_id, third_coin_id}
|
||||
|
|
|
@ -16,7 +16,6 @@ from chia.types.full_block import FullBlock
|
|||
from chia.types.blockchain_format.program import Program
|
||||
from chia.consensus.default_constants import DEFAULT_CONSTANTS
|
||||
from chia.wallet.puzzles.rom_bootstrap_generator import get_generator
|
||||
from chia.util.ints import uint32
|
||||
|
||||
GENERATOR_ROM = bytes(get_generator())
|
||||
|
||||
|
@ -24,7 +23,7 @@ GENERATOR_ROM = bytes(get_generator())
|
|||
# returns an optional error code and an optional PySpendBundleConditions (from chia_rs)
|
||||
# exactly one of those will hold a value and the number of seconds it took to
|
||||
# run
|
||||
def run_gen(env_data: bytes, block_program_args: bytes, flags: uint32):
|
||||
def run_gen(env_data: bytes, block_program_args: bytes, flags: int):
|
||||
max_cost = DEFAULT_CONSTANTS.MAX_BLOCK_COST_CLVM
|
||||
cost_per_byte = DEFAULT_CONSTANTS.COST_PER_BYTE
|
||||
|
||||
|
|
Loading…
Reference in a new issue