Skip to content

Commit

Permalink
add safe mode boolean
Browse files Browse the repository at this point in the history
no longer convert results to python
  • Loading branch information
matt-o-how authored and Yostra committed Jan 12, 2021
1 parent a2fc6d7 commit f50c615
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 69 deletions.
2 changes: 1 addition & 1 deletion src/consensus/cost_calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def calculate_cost_of_program(
This function calculates the total cost of either block or a spendbundle
"""
total_clvm_cost = 0
error, npc_list, cost = get_name_puzzle_conditions(program)
error, npc_list, cost = get_name_puzzle_conditions(program, True)
if error:
raise Exception("get_name_puzzle_conditions raised error" + str(error))
total_clvm_cost += cost
Expand Down
31 changes: 21 additions & 10 deletions src/full_node/mempool_check_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from src.types.spend_bundle import SpendBundle
from src.types.coin_record import CoinRecord
from src.types.name_puzzle_condition import NPC
from src.types.program import Program
from src.full_node.mempool import Mempool
from src.types.sized_bytes import bytes32
from src.util.clvm import int_from_bytes
from src.util.condition_tools import ConditionOpcode, conditions_by_opcode
Expand Down Expand Up @@ -99,26 +101,35 @@ def get_name_puzzle_conditions(block_program):
cost, result = GENERATOR_MOD.run_with_cost(block_program)
npc_list = []
opcodes = set(item.value for item in ConditionOpcode)
for res in result.as_python():
# TODO: as_python can cause blow up - use as_iter
for res in result.as_iter():
conditions_list = []
name = res[0]
puzzle_hash = bytes32(res[1])
for cond in res[2]:
if cond[0] in opcodes:
opcode = ConditionOpcode(cond[0])
else:
name = res.first().as_atom()
puzzle_hash = bytes32(res.rest().first().as_atom())
for cond in res.rest().rest().first().as_iter():
if cond.first().as_atom() in opcodes:
opcode = ConditionOpcode(cond.first().as_atom())
elif safe_mode:
opcode = ConditionOpcode.UNKNOWN
if len(cond) == 3:
cvp = ConditionVarPair(opcode, cond[1], cond[2])
else:
cvp = ConditionVarPair(opcode, cond[1])
raise Exception
# TODO: Rename CVP class
if len(list(cond.as_iter())) > 1:
cond_var_list = []
for cond in cond.rest().as_iter():
cond_var_list.append(cond.as_atom())
cvp = ConditionVarPair(opcode, *cond_var_list)
else:
cvp = ConditionVarPair(opcode)
conditions_list.append(cvp)
conditions_dict = conditions_by_opcode(conditions_list)
if conditions_dict is None:
conditions_dict = {}
npc_list.append(NPC(name, puzzle_hash, conditions_dict))
return None, npc_list, uint64(cost)

# TODO: write get puzzle and solution for coinname and blockprogram


def mempool_check_conditions_dict(
unspent: CoinRecord,
Expand Down
8 changes: 6 additions & 2 deletions src/types/full_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ def additions(self) -> List[Coin]:

if self.transactions_generator is not None:
# This should never throw here, block must be valid if it comes to here
err, npc_list, cost = get_name_puzzle_conditions(self.transactions_generator)
err, npc_list, cost = get_name_puzzle_conditions(
self.transactions_generator, False
)
# created coins
if npc_list is not None:
additions.extend(additions_for_npc(npc_list))
Expand All @@ -150,7 +152,9 @@ async def tx_removals_and_additions(self) -> Tuple[List[bytes32], List[Coin]]:

if self.transactions_generator is not None:
# This should never throw here, block must be valid if it comes to here
err, npc_list, cost = get_name_puzzle_conditions(self.transactions_generator)
err, npc_list, cost = get_name_puzzle_conditions(
self.transactions_generator, False
)
# build removals list
if npc_list is None:
return [], []
Expand Down
11 changes: 3 additions & 8 deletions src/wallet/puzzles/generator.clvm
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,10 @@
)
)

(defun len (arg count)
(if arg
(len (r arg) (+ count 1))
count
)
)

; TODO: this could be a macro
(defun npc_list_for_coinsolution (coin_solution)
(if (and (= (len coin_solution 0) 2) (= (len (f (r coin_solution)) 0) 2) (= (strlen (f coin_solution)) 32))
; The pattern (= (r (r foo)) ()) checks that foo is a list of length 2
(if (and (= (r (r coin_solution)) ()) (= (r (r (f (r coin_solution)))) ()) (= (strlen (f coin_solution)) 32))
(list (f coin_solution) (sha256tree1 (f (f (r coin_solution)))) ((c (f (f (r coin_solution))) (f (r (f (r coin_solution)))))))
(x)
)
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/puzzles/generator.clvm.hex
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ffff05ffff01ffffff05ff08ffff05ff02ffff05ffffff05ff03ffff01ff80808080ffff01ffff8080808080808080ffff05ffff01ffffffffff05ffff04ff05ffff01ffffff05ff08ffff05ff02ffff05ff0dffff05ffff05ffffff05ff0affff05ff02ffff05ff09ffff01ff808080808080ff0b80ffff01ff8080808080808080ffff01ff0b8080ff018080ffff05ffff04ff05ffff01ffffff05ff0cffff05ff02ffff05ff0dffff05ffff0cff0bffff01ff018080ffff01ff8080808080808080ffff01ff0b8080ff018080ffffff05ffff04ffffff05ffff04ffff0affffff05ff0cffff05ff02ffff05ff05ffff01ffff80808080808080ffff01ff028080ffff01ffffff05ffff04ffff0affffff05ff0cffff05ff02ffff05ff15ffff01ffff80808080808080ffff01ff028080ffff01ffffff05ffff04ffff0affff11ff0980ffff01ff208080ffff01ffff01ff018080ffff01ffff01ff80808080ff01808080ffff01ffff01ff80808080ff01808080ffff01ffff01ff80808080ff018080ffff01ffff05ff09ffff05ffffff05ff0effff05ff02ffff05ff25ffff01ff808080808080ffff05ffffff05ff25ff558080ffff01ff808080808080ffff01ffff09808080ff018080ffff05ffff04ffff08ff0580ffff01ffff0bffff01ff0280ffffff05ff0effff05ff02ffff05ff09ffff01ff808080808080ffffff05ff0effff05ff02ffff05ff0dffff01ff8080808080808080ffff01ffff0bffff01ff0180ff05808080ff01808080ff01808080
ffff05ffff01ffffff05ff04ffff05ff02ffff05ffffff05ff03ffff01ff80808080ffff01ffff8080808080808080ffff05ffff01ffffffff05ffff04ff05ffff01ffffff05ff04ffff05ff02ffff05ff0dffff05ffff05ffffff05ff0affff05ff02ffff05ff09ffff01ff808080808080ff0b80ffff01ff8080808080808080ffff01ff0b8080ff018080ffffff05ffff04ffffff05ffff04ffff0aff1dffff01ff808080ffff01ffffff05ffff04ffff0aff75ffff01ff808080ffff01ffffff05ffff04ffff0affff11ff0980ffff01ff208080ffff01ffff01ff018080ffff01ffff01ff80808080ff01808080ffff01ffff01ff80808080ff01808080ffff01ffff01ff80808080ff018080ffff01ffff05ff09ffff05ffffff05ff0effff05ff02ffff05ff25ffff01ff808080808080ffff05ffffff05ff25ff558080ffff01ff808080808080ffff01ffff09808080ff018080ffff05ffff04ffff08ff0580ffff01ffff0bffff01ff0280ffffff05ff0effff05ff02ffff05ff09ffff01ff808080808080ffffff05ff0effff05ff02ffff05ff0dffff01ff8080808080808080ffff01ffff0bffff01ff0180ff05808080ff01808080ff01808080
96 changes: 49 additions & 47 deletions tests/test_cost_calculation.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,49 @@
# import asyncio
#
# import pytest
#
# from src.full_node.bundle_tools import best_solution_program
# from src.consensus.cost_calculator import calculate_cost_of_program
# from src.full_node.mempool_check_conditions import get_name_puzzle_conditions
# from tests.setup_nodes import test_constants, bt
#
# BURN_PUZZLE_HASH = b"0" * 32
#
#
# @pytest.fixture(scope="module")
# def event_loop():
# loop = asyncio.get_event_loop()
# yield loop
#
#
# class TestCostCalculation:
# @pytest.mark.asyncio
# async def test_basics(self):
# wallet_tool = bt.get_pool_wallet_tool()
#
# num_blocks = 2
# blocks = bt.get_consecutive_blocks(
# test_constants,
# num_blocks,
# [],
# 10,
# )
#
# spend_bundle = wallet_tool.generate_signed_transaction(
# blocks[1].get_coinbase().amount,
# BURN_PUZZLE_HASH,
# blocks[1].get_coinbase(),
# )
# assert spend_bundle is not None
# program = best_solution_program(spend_bundle)
#
# ratio = test_constants.CLVM_COST_RATIO_CONSTANT
#
# error, npc_list, clvm_cost = calculate_cost_of_program(program, ratio)
#
# error, npc_list, cost = get_name_puzzle_conditions(program)
#
# # Create condition + agg_sig_condition + length + cpu_cost
# assert clvm_cost == 200 * ratio + 20 * ratio + len(bytes(program)) * ratio + cost
import asyncio

import pytest

from src.full_node.bundle_tools import best_solution_program
from src.full_node.cost_calculator import calculate_cost_of_program
from src.full_node.mempool_check_conditions import get_name_puzzle_conditions
from tests.setup_nodes import test_constants, bt

BURN_PUZZLE_HASH = b"0" * 32


@pytest.fixture(scope="module")
def event_loop():
loop = asyncio.get_event_loop()
yield loop


class TestCostCalculation:
@pytest.mark.asyncio
async def test_basics(self):
wallet_tool = bt.get_pool_wallet_tool()

num_blocks = 2
blocks = bt.get_consecutive_blocks(
test_constants,
num_blocks,
[],
10,
)

spend_bundle = wallet_tool.generate_signed_transaction(
blocks[1].get_coinbase().amount,
BURN_PUZZLE_HASH,
blocks[1].get_coinbase(),
)
assert spend_bundle is not None
program = best_solution_program(spend_bundle)

ratio = test_constants.CLVM_COST_RATIO_CONSTANT

error, npc_list, clvm_cost = calculate_cost_of_program(program, ratio)

error, npc_list, cost = get_name_puzzle_conditions(program, False)

# Create condition + agg_sig_condition + length + cpu_cost
assert (
clvm_cost == 200 * ratio + 20 * ratio + len(bytes(program)) * ratio + cost
)

0 comments on commit f50c615

Please sign in to comment.