Use Program instead of src.util.clvm.

This commit is contained in:
Richard Kiss 2020-09-15 17:11:37 -07:00 committed by Gene Hoffman
parent 92f2c3b4d9
commit 431ab0bf70
9 changed files with 39 additions and 53 deletions

View File

@ -7,7 +7,7 @@ from src.types.coin_record import CoinRecord
from src.types.name_puzzle_condition import NPC
from src.full_node.mempool import Mempool
from src.types.sized_bytes import bytes32
from src.util.clvm import EvalError, int_from_bytes, run_program
from src.util.clvm import int_from_bytes
from src.util.condition_tools import ConditionOpcode, conditions_dict_for_solution
from src.util.errors import Err
import time
@ -96,9 +96,9 @@ def get_name_puzzle_conditions(
"""
cost_sum = 0
try:
cost_run, sexp = run_program(block_program, [])
cost_run, sexp = block_program.run_with_cost([])
cost_sum += cost_run
except EvalError:
except Program.EvalError:
return Err.INVALID_COIN_SOLUTION, [], uint64(0)
npc_list = []
@ -121,7 +121,7 @@ def get_name_puzzle_conditions(
cost_sum += cost_run
if error:
return error, [], uint64(cost_sum)
except EvalError:
except Program.EvalError:
return Err.INVALID_COIN_SOLUTION, [], uint64(cost_sum)
if conditions_dict is None:
conditions_dict = {}

View File

@ -1,15 +1,17 @@
import io
from typing import Any, List, Set
from typing import Any, List, Optional, Set, Tuple
from src.types.sized_bytes import bytes32
from src.util.clvm import run_program, sexp_from_stream, sexp_to_stream
from clvm import SExp
from src.util.hash import std_hash
from clvm_tools.curry import curry
from clvm import SExp
from clvm.EvalError import EvalError
from clvm.casts import int_from_bytes
from clvm_tools.curry import curry, uncurry
class Program(SExp): # type: ignore # noqa
class Program(SExp):
"""
A thin wrapper around s-expression data intended to be invoked with "eval".
"""
@ -61,14 +63,25 @@ class Program(SExp): # type: ignore # noqa
"""
return self._tree_hash(set(args))
def run(self, args) -> "Program":
def run_with_cost(self, args) -> Tuple[int, "Program"]:
prog_args = Program.to(args)
cost, r = run_program(self, prog_args)
return run_program(self, prog_args)
def run(self, args) -> "Program":
cost, r = self.run_with_cost(args)
return Program.to(r)
def curry(self, *args) -> "Program":
cost, r = curry(self, list(args))
return Program.to(r)
def uncurry(self) -> Optional[Tuple["Program", "Program"]]:
return uncurry(self)
def as_int(self) -> int:
return int_from_bytes(self.as_atom())
def __deepcopy__(self, memo):
return type(self).from_bytes(bytes(self))
EvalError = EvalError

View File

@ -7,7 +7,7 @@ from src.types.condition_opcodes import ConditionOpcode
from src.types.coin import Coin
from src.types.program import Program
from src.types.sized_bytes import bytes32
from src.util.clvm import EvalError, int_from_bytes, run_program
from src.util.clvm import int_from_bytes
from src.util.ints import uint64
from src.util.errors import Err, ConsensusError
@ -121,15 +121,15 @@ def conditions_dict_for_solution(
def conditions_for_solution(
solution_program, run_program=run_program
solution_program,
) -> Tuple[Optional[Err], Optional[List[ConditionVarPair]], uint64]:
# get the standard script for a puzzle hash and feed in the solution
args = Program.to(solution_program)
try:
puzzle_sexp = args.first()
solution_sexp = args.rest().first()
cost, r = run_program(puzzle_sexp, solution_sexp)
cost, r = puzzle_sexp.run_with_cost(solution_sexp)
error, result = parse_sexp_to_conditions(r)
return error, result, cost
except EvalError:
except Program.EvalError:
return Err.SEXP_ERROR, None, uint64(0)

View File

@ -224,7 +224,7 @@ def uncurry_cc(puzzle: Program) -> Optional[Tuple[Program, Program, Program]]:
Take a puzzle and return `None` if it's not a `CC_MOD` cc, or
a triple of `mod_hash, genesis_coin_checker, inner_puzzle` if it is.
"""
r = uncurry(puzzle)
r = puzzle.uncurry()
if r is None:
return r
inner_f, args = r

View File

@ -11,7 +11,6 @@ from src.types.program import Program
from src.types.spend_bundle import SpendBundle
from src.types.sized_bytes import bytes32
from src.util.byte_types import hexstr_to_bytes
from src.util.clvm import EvalError, run_program
from src.util.condition_tools import (
conditions_dict_for_solution,
pkm_pairs_for_conditions_dict,
@ -296,9 +295,9 @@ class CCWallet:
"""
cost_sum = 0
try:
cost_run, sexp = run_program(block_program, [])
cost_run, sexp = block_program.run_with_cost([])
cost_sum += cost_run
except EvalError:
except Program.EvalError:
return False
for name_solution in sexp.as_iter():
@ -319,7 +318,7 @@ class CCWallet:
cost_sum += cost_run
if error:
return False
except EvalError:
except Program.EvalError:
return False
if conditions_dict is None:

View File

@ -4,8 +4,6 @@ from clvm import KEYWORD_FROM_ATOM
from clvm_tools.binutils import disassemble as bu_disassemble
from stages.stage_0 import run_program
from src.types.coin import Coin
from src.types.condition_opcodes import ConditionOpcode
from src.types.program import Program
@ -53,7 +51,7 @@ def debug_spend_bundle(spend_bundle: SpendBundle) -> None:
print("=" * 80)
for coin_solution in spend_bundle.coin_solutions:
coin, solution_pair = coin_solution.coin, coin_solution.solution
coin, solution_pair = coin_solution.coin, Program.to(coin_solution.solution)
puzzle_reveal = solution_pair.first()
solution = solution_pair.rest().first()
@ -70,7 +68,7 @@ def debug_spend_bundle(spend_bundle: SpendBundle) -> None:
print(f"*** error {error}")
else:
print()
cost, r = run_program(puzzle_reveal, solution)
r = puzzle_reveal.run(solution)
print(disassemble(r))
print()
if conditions and len(conditions) > 0:

View File

@ -1,7 +1,5 @@
from typing import Optional
from clvm_tools.curry import curry as ct_curry, uncurry
from src.types.coin import Coin
from src.types.program import Program
from src.types.sized_bytes import bytes32
@ -11,22 +9,13 @@ from src.wallet.puzzles.load_clvm import load_clvm
MOD = load_clvm("genesis-by-coin-id-with-0.clvm", package_or_requirement=__name__)
def curry(*args, **kwargs):
"""
The clvm_tools version of curry returns `cost, program` for now.
Eventually it will just return `program`. This placeholder awaits that day.
"""
cost, prog = ct_curry(*args, **kwargs)
return Program.to(prog)
def create_genesis_or_zero_coin_checker(genesis_coin_id: bytes32) -> Program:
"""
Given a specific genesis coin id, create a `genesis_coin_mod` that allows
both that coin id to issue a cc, or anyone to create a cc with amount 0.
"""
genesis_coin_mod = MOD
return curry(genesis_coin_mod, [genesis_coin_id])
return genesis_coin_mod.curry(genesis_coin_id)
def genesis_coin_id_for_genesis_coin_checker(
@ -35,7 +24,7 @@ def genesis_coin_id_for_genesis_coin_checker(
"""
Given a `genesis_coin_checker` program, pull out the genesis coin id.
"""
r = uncurry(genesis_coin_checker)
r = genesis_coin_checker.uncurry()
if r is None:
return r
f, args = r

View File

@ -1,7 +1,5 @@
from typing import Optional
from clvm_tools.curry import curry as ct_curry, uncurry
from src.types.coin import Coin
from src.types.program import Program
from src.types.sized_bytes import bytes32
@ -11,22 +9,13 @@ from src.wallet.puzzles.load_clvm import load_clvm
MOD = load_clvm("genesis-by-puzzle-hash-with-0.clvm", package_or_requirement=__name__)
def curry(*args, **kwargs):
"""
The clvm_tools version of curry returns `cost, program` for now.
Eventually it will just return `program`. This placeholder awaits that day.
"""
cost, prog = ct_curry(*args, **kwargs)
return Program.to(prog)
def create_genesis_puzzle_or_zero_coin_checker(genesis_puzzle_hash: bytes32) -> Program:
"""
Given a specific genesis coin id, create a `genesis_coin_mod` that allows
both that coin id to issue a cc, or anyone to create a cc with amount 0.
"""
genesis_coin_mod = MOD
return curry(genesis_coin_mod, [genesis_puzzle_hash])
return genesis_coin_mod.curry(genesis_puzzle_hash)
def genesis_puzzle_hash_for_genesis_coin_checker(
@ -35,7 +24,7 @@ def genesis_puzzle_hash_for_genesis_coin_checker(
"""
Given a `genesis_coin_checker` program, pull out the genesis puzzle hash.
"""
r = uncurry(genesis_coin_checker)
r = genesis_coin_checker.uncurry()
if r is None:
return r
f, args = r
@ -53,7 +42,6 @@ def lineage_proof_for_zero(parent_coin: Coin) -> Program:
def lineage_proof_for_coin(parent_coin: Coin) -> Program:
breakpoint()
if parent_coin.amount == 0:
return lineage_proof_for_zero(parent_coin)
return lineage_proof_for_genesis_puzzle(parent_coin)

View File

@ -8,7 +8,6 @@ from src.types.condition_opcodes import ConditionOpcode
from src.types.condition_var_pair import ConditionVarPair
from src.types.program import Program
from src.wallet.puzzles.p2_delegated_puzzle import puzzle_for_pk
from src.util.clvm import run_program
from src.util.wallet_tools import WalletTool
from src.util.ints import uint32
from src.wallet.derive_keys import master_sk_to_wallet_sk
@ -42,7 +41,7 @@ def run_and_return_cost_time(chialisp):
clvm_loop_solution = f"(1000 {chialisp})"
solution_program = Program(binutils.assemble(clvm_loop_solution))
cost, sexp = run_program(loop_program, solution_program)
cost, sexp = loop_program.run_with_cost(solution_program)
end = time.time()
total_time = end - start
@ -156,7 +155,7 @@ if __name__ == "__main__":
puzzle_start = time.time()
clvm_cost = 0
for i in range(0, 1000):
cost_run, sexp = run_program(puzzles[i], solutions[i])
cost_run, sexp = puzzles[i].run_with_cost(solutions[i])
clvm_cost += cost_run
puzzle_end = time.time()