Add test for relative seconds, and rename conditions (#1902)

* Add test for relative seconds

* rebased on top of main

* Renamed AGG_SIG to AGG_SIG_UNSAFE
Renamed height and time conditions
Changed some demo p2 puzzles to use AGG_SIG_ME

* fix merge on cost_calculator

* update hex and sha256tree of p2_delegated_conditions

* fix condition name in rl clvm

* updated the innerpuz sha256tree after careful inspection
This commit is contained in:
matt-o-how 2021-04-15 21:00:14 +01:00 committed by GitHub
parent 24fdd378a7
commit 332d9392f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 173 additions and 104 deletions

View File

@ -17,7 +17,7 @@ def blockchain_assert_my_coin_id(condition: ConditionWithArgs, unspent: CoinReco
return None
def blockchain_assert_block_index_exceeds(
def blockchain_assert_absolute_block_height_exceeds(
condition: ConditionWithArgs, prev_transaction_block_height: uint32
) -> Optional[Err]:
"""
@ -29,11 +29,11 @@ def blockchain_assert_block_index_exceeds(
return Err.INVALID_CONDITION
if prev_transaction_block_height < expected_block_index:
return Err.ASSERT_HEIGHT_NOW_EXCEEDS_FAILED
return Err.ASSERT_HEIGHT_ABSOLUTE_FAILED
return None
def blockchain_assert_block_age_exceeds(
def blockchain_assert_relative_block_height_exceeds(
condition: ConditionWithArgs, unspent: CoinRecord, prev_transaction_block_height: uint32
) -> Optional[Err]:
"""
@ -45,11 +45,11 @@ def blockchain_assert_block_age_exceeds(
except ValueError:
return Err.INVALID_CONDITION
if prev_transaction_block_height < expected_block_index:
return Err.ASSERT_HEIGHT_AGE_EXCEEDS_FAILED
return Err.ASSERT_HEIGHT_RELATIVE_FAILED
return None
def blockchain_assert_time_exceeds(condition: ConditionWithArgs, timestamp):
def blockchain_assert_absolute_time_exceeds(condition: ConditionWithArgs, timestamp):
"""
Checks if current time in millis exceeds the time specified in condition
"""
@ -60,7 +60,7 @@ def blockchain_assert_time_exceeds(condition: ConditionWithArgs, timestamp):
current_time = timestamp
if current_time <= expected_mili_time:
return Err.ASSERT_SECONDS_NOW_EXCEEDS_FAILED
return Err.ASSERT_SECONDS_ABSOLUTE_FAILED
return None
@ -75,7 +75,7 @@ def blockchain_assert_relative_time_exceeds(condition: ConditionWithArgs, unspen
current_time = timestamp
if current_time <= expected_mili_time + unspent.timestamp:
return Err.ASSERT_SECONDS_AGE_EXCEEDS_FAILED
return Err.ASSERT_SECONDS_RELATIVE_FAILED
return None
@ -111,13 +111,13 @@ def blockchain_check_conditions_dict(
error = blockchain_assert_announcement(cvp, coin_announcement_names)
elif cvp.opcode is ConditionOpcode.ASSERT_PUZZLE_ANNOUNCEMENT:
error = blockchain_assert_announcement(cvp, puzzle_announcement_names)
elif cvp.opcode is ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS:
error = blockchain_assert_block_index_exceeds(cvp, prev_transaction_block_height)
elif cvp.opcode is ConditionOpcode.ASSERT_HEIGHT_AGE_EXCEEDS:
error = blockchain_assert_block_age_exceeds(cvp, unspent, prev_transaction_block_height)
elif cvp.opcode is ConditionOpcode.ASSERT_SECONDS_NOW_EXCEEDS:
error = blockchain_assert_time_exceeds(cvp, timestamp)
elif cvp.opcode is ConditionOpcode.ASSERT_SECONDS_AGE_EXCEEDS:
elif cvp.opcode is ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE:
error = blockchain_assert_absolute_block_height_exceeds(cvp, prev_transaction_block_height)
elif cvp.opcode is ConditionOpcode.ASSERT_HEIGHT_RELATIVE:
error = blockchain_assert_relative_block_height_exceeds(cvp, unspent, prev_transaction_block_height)
elif cvp.opcode is ConditionOpcode.ASSERT_SECONDS_ABSOLUTE:
error = blockchain_assert_absolute_time_exceeds(cvp, timestamp)
elif cvp.opcode is ConditionOpcode.ASSERT_SECONDS_RELATIVE:
error = blockchain_assert_relative_time_exceeds(cvp, unspent, timestamp)
if error:
return error

View File

@ -6,10 +6,10 @@ class ConditionCost(Enum):
AGG_SIG = 1200000 # the cost of one G1 subgroup check + aggregated signature validation
CREATE_COIN = 1800000
ASSERT_MY_COIN_ID = 0
ASSERT_SECONDS_NOW_EXCEEDS = 0
ASSERT_SECONDS_AGE_EXCEEDS = 0
ASSERT_HEIGHT_NOW_EXCEEDS = 0
ASSERT_HEIGHT_AGE_EXCEEDS = 0
ASSERT_SECONDS_RELATIVE = 0
ASSERT_SECONDS_ABSOLUTE = 0
ASSERT_HEIGHT_RELATIVE = 0
ASSERT_HEIGHT_ABSOLUTE = 0
RESERVE_FEE = 0
CREATE_COIN_ANNOUNCEMENT = 0
ASSERT_COIN_ANNOUNCEMENT = 0

View File

@ -32,16 +32,18 @@ def calculate_cost_of_program(program: SerializedProgram, cost_per_byte: int, st
npc: NPC
for npc in npc_list:
for condition, cvp_list in npc.condition_dict.items():
if condition is ConditionOpcode.AGG_SIG or condition is ConditionOpcode.AGG_SIG_ME:
if condition is ConditionOpcode.AGG_SIG_UNSAFE or condition is ConditionOpcode.AGG_SIG_ME:
total_cost += len(cvp_list) * ConditionCost.AGG_SIG.value
elif condition is ConditionOpcode.CREATE_COIN:
total_cost += len(cvp_list) * ConditionCost.CREATE_COIN.value
elif condition is ConditionOpcode.ASSERT_SECONDS_NOW_EXCEEDS:
total_cost += len(cvp_list) * ConditionCost.ASSERT_SECONDS_NOW_EXCEEDS.value
elif condition is ConditionOpcode.ASSERT_HEIGHT_AGE_EXCEEDS:
total_cost += len(cvp_list) * ConditionCost.ASSERT_HEIGHT_AGE_EXCEEDS.value
elif condition is ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS:
total_cost += len(cvp_list) * ConditionCost.ASSERT_HEIGHT_NOW_EXCEEDS.value
elif condition is ConditionOpcode.ASSERT_SECONDS_ABSOLUTE:
total_cost += len(cvp_list) * ConditionCost.ASSERT_SECONDS_ABSOLUTE.value
elif condition is ConditionOpcode.ASSERT_HEIGHT_RELATIVE:
total_cost += len(cvp_list) * ConditionCost.ASSERT_HEIGHT_RELATIVE.value
elif condition is ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE:
total_cost += len(cvp_list) * ConditionCost.ASSERT_HEIGHT_ABSOLUTE.value
elif condition is ConditionOpcode.ASSERT_HEIGHT_RELATIVE:
total_cost += len(cvp_list) * ConditionCost.ASSERT_HEIGHT_RELATIVE.value
elif condition is ConditionOpcode.ASSERT_MY_COIN_ID:
total_cost += len(cvp_list) * ConditionCost.ASSERT_MY_COIN_ID.value
elif condition is ConditionOpcode.RESERVE_FEE:

View File

@ -38,7 +38,7 @@ def mempool_assert_my_coin_id(condition: ConditionWithArgs, unspent: CoinRecord)
return None
def mempool_assert_block_index_exceeds(
def mempool_assert_absolute_block_height_exceeds(
condition: ConditionWithArgs, prev_transaction_block_height: uint32
) -> Optional[Err]:
"""
@ -49,11 +49,11 @@ def mempool_assert_block_index_exceeds(
except ValueError:
return Err.INVALID_CONDITION
if prev_transaction_block_height < block_index_exceeds_this:
return Err.ASSERT_HEIGHT_NOW_EXCEEDS_FAILED
return Err.ASSERT_HEIGHT_ABSOLUTE_FAILED
return None
def mempool_assert_block_age_exceeds(
def mempool_assert_relative_block_height_exceeds(
condition: ConditionWithArgs, unspent: CoinRecord, prev_transaction_block_height: uint32
) -> Optional[Err]:
"""
@ -65,11 +65,11 @@ def mempool_assert_block_age_exceeds(
except ValueError:
return Err.INVALID_CONDITION
if prev_transaction_block_height < block_index_exceeds_this:
return Err.ASSERT_HEIGHT_AGE_EXCEEDS_FAILED
return Err.ASSERT_HEIGHT_RELATIVE_FAILED
return None
def mempool_assert_time_exceeds(condition: ConditionWithArgs) -> Optional[Err]:
def mempool_assert_absolute_time_exceeds(condition: ConditionWithArgs) -> Optional[Err]:
"""
Check if the current time in millis exceeds the time specified by condition
"""
@ -80,7 +80,7 @@ def mempool_assert_time_exceeds(condition: ConditionWithArgs) -> Optional[Err]:
current_time = uint64(int(time.time() * 1000))
if current_time <= expected_mili_time:
return Err.ASSERT_SECONDS_NOW_EXCEEDS_FAILED
return Err.ASSERT_SECONDS_ABSOLUTE_FAILED
return None
@ -95,7 +95,7 @@ def mempool_assert_relative_time_exceeds(condition: ConditionWithArgs, unspent:
current_time = uint64(int(time.time() * 1000))
if current_time <= expected_mili_time + unspent.timestamp:
return Err.ASSERT_SECONDS_NOW_EXCEEDS_FAILED
return Err.ASSERT_SECONDS_ABSOLUTE_FAILED
return None
@ -200,13 +200,13 @@ def mempool_check_conditions_dict(
error = mempool_assert_announcement(cvp, coin_announcement_names)
elif cvp.opcode is ConditionOpcode.ASSERT_PUZZLE_ANNOUNCEMENT:
error = mempool_assert_announcement(cvp, puzzle_announcement_names)
elif cvp.opcode is ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS:
error = mempool_assert_block_index_exceeds(cvp, prev_transaction_block_height)
elif cvp.opcode is ConditionOpcode.ASSERT_HEIGHT_AGE_EXCEEDS:
error = mempool_assert_block_age_exceeds(cvp, unspent, prev_transaction_block_height)
elif cvp.opcode is ConditionOpcode.ASSERT_SECONDS_NOW_EXCEEDS:
error = mempool_assert_time_exceeds(cvp)
elif cvp.opcode is ConditionOpcode.ASSERT_SECONDS_AGE_EXCEEDS:
elif cvp.opcode is ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE:
error = mempool_assert_absolute_block_height_exceeds(cvp, prev_transaction_block_height)
elif cvp.opcode is ConditionOpcode.ASSERT_HEIGHT_RELATIVE:
error = mempool_assert_relative_block_height_exceeds(cvp, unspent, prev_transaction_block_height)
elif cvp.opcode is ConditionOpcode.ASSERT_SECONDS_ABSOLUTE:
error = mempool_assert_absolute_time_exceeds(cvp)
elif cvp.opcode is ConditionOpcode.ASSERT_SECONDS_RELATIVE:
error = mempool_assert_relative_time_exceeds(cvp, unspent)
elif cvp.opcode is ConditionOpcode.ASSERT_MY_PARENT_ID:
error = mempool_assert_my_parent_id(cvp, unspent)

View File

@ -336,7 +336,7 @@ class MempoolManager:
)
if error:
if error is Err.ASSERT_HEIGHT_NOW_EXCEEDS_FAILED or error is Err.ASSERT_HEIGHT_AGE_EXCEEDS_FAILED:
if error is Err.ASSERT_HEIGHT_ABSOLUTE_FAILED or error is Err.ASSERT_HEIGHT_RELATIVE_FAILED:
self.add_to_potential_tx_set(new_spend, spend_name, cost_result)
return uint64(cost), MempoolInclusionStatus.PENDING, error
break

View File

@ -11,7 +11,7 @@ class ConditionOpcode(bytes, enum.Enum):
# the conditions below require bls12-381 signatures
AGG_SIG = bytes([49])
AGG_SIG_UNSAFE = bytes([49])
AGG_SIG_ME = bytes([50])
# the conditions below reserve coin amounts and have to be accounted for in output totals
@ -36,12 +36,12 @@ class ConditionOpcode(bytes, enum.Enum):
# the conditions below ensure that we're "far enough" in the future
# wall-clock time
ASSERT_SECONDS_AGE_EXCEEDS = bytes([80])
ASSERT_SECONDS_NOW_EXCEEDS = bytes([81])
ASSERT_SECONDS_RELATIVE = bytes([80])
ASSERT_SECONDS_ABSOLUTE = bytes([81])
# block index
ASSERT_HEIGHT_AGE_EXCEEDS = bytes([82])
ASSERT_HEIGHT_NOW_EXCEEDS = bytes([83])
ASSERT_HEIGHT_RELATIVE = bytes([82])
ASSERT_HEIGHT_ABSOLUTE = bytes([83])
def __bytes__(self) -> bytes:
return bytes(self.value)

View File

@ -73,7 +73,7 @@ def pkm_pairs_for_conditions_dict(
assert coin_name is not None
ret: List[Tuple[G1Element, bytes]] = []
for cwa in conditions_dict.get(ConditionOpcode.AGG_SIG, []):
for cwa in conditions_dict.get(ConditionOpcode.AGG_SIG_UNSAFE, []):
assert len(cwa.vars) == 2
assert cwa.vars[0] is not None and cwa.vars[1] is not None
ret.append((G1Element.from_bytes(cwa.vars[0]), cwa.vars[1]))

View File

@ -32,9 +32,9 @@ class Err(Enum):
INVALID_CONDITION = 10
ASSERT_MY_COIN_ID_FAILED = 11
ASSERT_ANNOUNCE_CONSUMED_FAILED = 12
ASSERT_HEIGHT_AGE_EXCEEDS_FAILED = 13
ASSERT_HEIGHT_NOW_EXCEEDS_FAILED = 14
ASSERT_SECONDS_NOW_EXCEEDS_FAILED = 15
ASSERT_HEIGHT_RELATIVE_FAILED = 13
ASSERT_HEIGHT_ABSOLUTE_FAILED = 14
ASSERT_SECONDS_ABSOLUTE_FAILED = 15
COIN_AMOUNT_EXCEEDS_MAXIMUM = 16
SEXP_ERROR = 17
@ -127,7 +127,7 @@ class Err(Enum):
TOO_MANY_BLOCKS = 102
INVALID_CC_CHALLENGE = 103
INVALID_PREFARM = 104
ASSERT_SECONDS_AGE_EXCEEDS_FAILED = 105
ASSERT_SECONDS_RELATIVE_FAILED = 105
BAD_COINBASE_SIGNATURE = 106
INITIAL_TRANSACTION_FREEZE = 107
NO_TRANSACTIONS_WHILE_SYNCING = 108

View File

@ -24,10 +24,11 @@ from chia.wallet.puzzles.puzzle_utils import (
make_assert_aggsig_condition,
make_assert_coin_announcement,
make_assert_puzzle_announcement,
make_assert_height_age_exceeds_condition,
make_assert_height_now_exceeds_condition,
make_assert_relative_height_exceeds_condition,
make_assert_absolute_height_exceeds_condition,
make_assert_my_coin_id_condition,
make_assert_seconds_now_exceeds_condition,
make_assert_absolute_seconds_exceeds_condition,
make_assert_relative_seconds_exceeds_condition,
make_create_coin_announcement,
make_create_puzzle_announcement,
make_create_coin_condition,
@ -106,20 +107,22 @@ class WalletTool:
ret.append(make_create_coin_announcement(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT:
ret.append(make_create_puzzle_announcement(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.AGG_SIG:
if cvp.opcode == ConditionOpcode.AGG_SIG_UNSAFE:
ret.append(make_assert_aggsig_condition(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT:
ret.append(make_assert_coin_announcement(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.ASSERT_PUZZLE_ANNOUNCEMENT:
ret.append(make_assert_puzzle_announcement(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.ASSERT_SECONDS_NOW_EXCEEDS:
ret.append(make_assert_seconds_now_exceeds_condition(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.ASSERT_SECONDS_ABSOLUTE:
ret.append(make_assert_absolute_seconds_exceeds_condition(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.ASSERT_SECONDS_RELATIVE:
ret.append(make_assert_relative_seconds_exceeds_condition(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.ASSERT_MY_COIN_ID:
ret.append(make_assert_my_coin_id_condition(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS:
ret.append(make_assert_height_now_exceeds_condition(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.ASSERT_HEIGHT_AGE_EXCEEDS:
ret.append(make_assert_height_age_exceeds_condition(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE:
ret.append(make_assert_absolute_height_exceeds_condition(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.ASSERT_HEIGHT_RELATIVE:
ret.append(make_assert_relative_height_exceeds_condition(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.RESERVE_FEE:
ret.append(make_reserve_fee_condition(cvp.vars[0]))
if cvp.opcode == ConditionOpcode.ASSERT_MY_PARENT_ID:

View File

@ -82,7 +82,7 @@ def get_innerpuzzle_from_puzzle(puzzle: Program) -> Optional[Program]:
def create_recovery_message_puzzle(recovering_coin: bytes32, newpuz: bytes32, pubkey: G1Element):
puzstring = f"(q . ((0x{ConditionOpcode.CREATE_COIN_ANNOUNCEMENT.hex()} 0x{recovering_coin.hex()}) (0x{ConditionOpcode.AGG_SIG.hex()} 0x{bytes(pubkey).hex()} 0x{newpuz.hex()})))" # noqa
puzstring = f"(q . ((0x{ConditionOpcode.CREATE_COIN_ANNOUNCEMENT.hex()} 0x{recovering_coin.hex()}) (0x{ConditionOpcode.AGG_SIG_UNSAFE.hex()} 0x{bytes(pubkey).hex()} 0x{newpuz.hex()})))" # noqa
puz = binutils.assemble(puzstring)
return Program.to(puz)

View File

@ -1,7 +1,7 @@
; See chia/types/condition_opcodes.py
(
(defconstant AGG_SIG 49)
(defconstant AGG_SIG_UNSAFE 49)
(defconstant AGG_SIG_ME 50)
; the conditions below reserve coin amounts and have to be accounted for in output totals
@ -29,10 +29,10 @@
; the conditions below ensure that we're "far enough" in the future
; wall-clock time
(defconstant ASSERT_SECONDS_AGE_EXCEEDS 80)
(defconstant ASSERT_SECONDS_NOW_EXCEEDS 81)
(defconstant ASSERT_SECONDS_RELATIVE 80)
(defconstant ASSERT_SECONDS_ABSOLUTE 81)
; block index
(defconstant ASSERT_HEIGHT_AGE_EXCEEDS 82)
(defconstant ASSERT_HEIGHT_NOW_EXCEEDS 83)
(defconstant ASSERT_HEIGHT_RELATIVE 82)
(defconstant ASSERT_HEIGHT_ABSOLUTE 83)
)

View File

@ -76,7 +76,7 @@
;recovery message module - gets values curried in to make the puzzle
;TODO - this should probably be imported
(defun make_message_puzzle (recovering_coin newpuz pubkey)
(qq (q . (((unquote CREATE_COIN_ANNOUNCEMENT) (unquote recovering_coin)) ((unquote AGG_SIG) (unquote pubkey) (unquote newpuz)))))
(qq (q . (((unquote CREATE_COIN_ANNOUNCEMENT) (unquote recovering_coin)) ((unquote AGG_SIG_UNSAFE) (unquote pubkey) (unquote newpuz)))))
)
(defun create_consume_message (coin_id my_id new_innerpuz pubkey)
@ -146,9 +146,9 @@
)
;if we're out of identites to check for, return our output
(if (> num_verifications num_verifications_required)
(c (list AGG_SIG pubkey new_puz) output)
(c (list AGG_SIG_UNSAFE pubkey new_puz) output)
(if (= num_verifications num_verifications_required)
(c (list AGG_SIG pubkey new_puz) output)
(c (list AGG_SIG_UNSAFE pubkey new_puz) output)
(x "not enough verifications")
)
)

View File

@ -1 +1 @@
ff02ffff01ff02ffff03ff5fffff01ff02ffff03ffff09ff5fffff010180ffff01ff04ffff04ff38ffff04ff8205ffffff04ff81bfff80808080ffff04ffff04ff38ffff04ff82017fffff01ff80808080ffff04ffff04ff30ffff04ff0bffff04ff82017fff80808080ff80808080ffff01ff02ffff03ff822fffffff01ff02ffff03ffff09ffff02ff2effff04ff02ffff04ff822fffff80808080ff1780ffff01ff02ff34ffff04ff02ffff04ff05ffff04ffff02ff2effff04ff02ffff04ff05ff80808080ffff04ff2fffff04ff822fffffff04ff8202ffffff04ffff04ffff04ff38ffff04ff82017fffff04ff81bfff80808080ff8080ffff04ff82017fffff04ff820bffffff04ff8217ffffff01ff80808080808080808080808080ffff01ff08ffff01a77265636f76657279206c6973742072657665616c20646964206e6f74206d6174636820686173688080ff0180ffff01ff08ffff0195444944207265636f766572792064697361626c65648080ff018080ff0180ffff01ff04ffff04ff38ffff04ff82017fffff04ff81bfff80808080ffff04ffff04ff30ffff04ff0bffff04ff82017fff80808080ff80808080ff0180ffff04ffff01ffffffff3132ff3d33ffff3cff02ffff03ff2fffff01ff02ffff03ff8204ffffff01ff02ff34ffff04ff02ffff04ff05ffff04ff0bffff04ff17ffff04ff6fffff04ff5fffff04ffff04ffff02ff3cffff04ff02ffff04ffff02ff2cffff04ff02ffff04ff05ffff04ff0bffff04ff4fffff04ff8208ffffff04ff8214ffffff04ff822cffff808080808080808080ffff04ff5fffff04ff82017fffff04ff8205ffff80808080808080ff81bf80ffff04ff82017fffff04ff8206ffffff04ff8205ffffff04ffff10ff820bffffff010180ff80808080808080808080808080ffff01ff02ff34ffff04ff02ffff04ff05ffff04ff0bffff04ff17ffff04ff6fffff04ff5fffff04ff81bfffff04ff82017fffff04ff8206ffffff04ff8205ffffff04ff820bffff8080808080808080808080808080ff0180ffff01ff02ffff03ffff15ff820bffff1780ffff01ff04ffff04ff20ffff04ff8205ffffff04ff82017fff80808080ff81bf80ffff01ff02ffff03ffff09ff820bffff1780ffff01ff04ffff04ff20ffff04ff8205ffffff04ff82017fff80808080ff81bf80ffff01ff08ffff01986e6f7420656e6f75676820766572696669636174696f6e738080ff018080ff018080ff0180ffff0bff2fffff02ff22ffff04ff02ffff04ff05ffff04ff0bffff04ff17ffff04ff5fff80808080808080ff81bf80ff04ff28ffff04ffff0bffff0bff05ffff02ff2effff04ff02ffff04ffff02ff36ffff04ff02ffff04ff0bffff04ff17ffff04ff2fff808080808080ff8080808080ff0b80ff808080ffffffff02ff5effff04ff02ffff04ffff02ff32ffff04ff02ffff04ff05ffff04ff0bffff04ff17ffff04ff2fff80808080808080ffff04ff05ffff04ff0bffff04ff2fff80808080808080ff02ff2affff04ff02ffff04ff05ffff04ff07ff8080808080ffff04ffff0102ffff04ffff04ffff0101ff0580ffff04ffff02ff3affff04ff02ffff04ff0bffff01ff0180808080ff80808080ff02ffff03ff05ffff01ff04ffff0104ffff04ffff04ffff0101ff0980ffff04ffff02ff3affff04ff02ffff04ff0dffff04ff0bff8080808080ff80808080ffff010b80ff0180ffffff02ffff03ff0bffff01ff02ffff03ffff09ff05ff1380ffff01ff0101ffff01ff02ff26ffff04ff02ffff04ff05ffff04ff1bff808080808080ff0180ff8080ff0180ff04ffff0101ffff04ffff04ff24ffff04ff05ff808080ffff04ffff04ff20ffff04ff17ffff04ff0bff80808080ff80808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ffff02ff7effff04ff02ffff04ff05ffff04ff07ff8080808080ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff7effff04ff02ffff04ff09ffff04ff0bff8080808080ffff02ff7effff04ff02ffff04ff0dffff04ff0bff808080808080ffff01ff02ffff03ffff02ff26ffff04ff02ffff04ff05ffff04ff0bff8080808080ffff0105ffff01ff0bffff0101ff058080ff018080ff0180ff018080
ff02ffff01ff02ffff03ff5fffff01ff02ffff03ffff09ff5fffff010180ffff01ff04ffff04ff38ffff04ff8205ffffff04ff81bfff80808080ffff04ffff04ff38ffff04ff82017fffff01ff80808080ffff04ffff04ff20ffff04ff0bffff04ff82017fff80808080ff80808080ffff01ff02ffff03ff822fffffff01ff02ffff03ffff09ffff02ff2effff04ff02ffff04ff822fffff80808080ff1780ffff01ff02ff34ffff04ff02ffff04ff05ffff04ffff02ff2effff04ff02ffff04ff05ff80808080ffff04ff2fffff04ff822fffffff04ff8202ffffff04ffff04ffff04ff38ffff04ff82017fffff04ff81bfff80808080ff8080ffff04ff82017fffff04ff820bffffff04ff8217ffffff01ff80808080808080808080808080ffff01ff08ffff01a77265636f76657279206c6973742072657665616c20646964206e6f74206d6174636820686173688080ff0180ffff01ff08ffff0195444944207265636f766572792064697361626c65648080ff018080ff0180ffff01ff04ffff04ff38ffff04ff82017fffff04ff81bfff80808080ffff04ffff04ff20ffff04ff0bffff04ff82017fff80808080ff80808080ff0180ffff04ffff01ffffffff3231ff3d33ffff3cff02ffff03ff2fffff01ff02ffff03ff8204ffffff01ff02ff34ffff04ff02ffff04ff05ffff04ff0bffff04ff17ffff04ff6fffff04ff5fffff04ffff04ffff02ff3cffff04ff02ffff04ffff02ff2cffff04ff02ffff04ff05ffff04ff0bffff04ff4fffff04ff8208ffffff04ff8214ffffff04ff822cffff808080808080808080ffff04ff5fffff04ff82017fffff04ff8205ffff80808080808080ff81bf80ffff04ff82017fffff04ff8206ffffff04ff8205ffffff04ffff10ff820bffffff010180ff80808080808080808080808080ffff01ff02ff34ffff04ff02ffff04ff05ffff04ff0bffff04ff17ffff04ff6fffff04ff5fffff04ff81bfffff04ff82017fffff04ff8206ffffff04ff8205ffffff04ff820bffff8080808080808080808080808080ff0180ffff01ff02ffff03ffff15ff820bffff1780ffff01ff04ffff04ff30ffff04ff8205ffffff04ff82017fff80808080ff81bf80ffff01ff02ffff03ffff09ff820bffff1780ffff01ff04ffff04ff30ffff04ff8205ffffff04ff82017fff80808080ff81bf80ffff01ff08ffff01986e6f7420656e6f75676820766572696669636174696f6e738080ff018080ff018080ff0180ffff0bff2fffff02ff22ffff04ff02ffff04ff05ffff04ff0bffff04ff17ffff04ff5fff80808080808080ff81bf80ff04ff28ffff04ffff0bffff0bff05ffff02ff2effff04ff02ffff04ffff02ff36ffff04ff02ffff04ff0bffff04ff17ffff04ff2fff808080808080ff8080808080ff0b80ff808080ffffffff02ff5effff04ff02ffff04ffff02ff32ffff04ff02ffff04ff05ffff04ff0bffff04ff17ffff04ff2fff80808080808080ffff04ff05ffff04ff0bffff04ff2fff80808080808080ff02ff2affff04ff02ffff04ff05ffff04ff07ff8080808080ffff04ffff0102ffff04ffff04ffff0101ff0580ffff04ffff02ff3affff04ff02ffff04ff0bffff01ff0180808080ff80808080ff02ffff03ff05ffff01ff04ffff0104ffff04ffff04ffff0101ff0980ffff04ffff02ff3affff04ff02ffff04ff0dffff04ff0bff8080808080ff80808080ffff010b80ff0180ffffff02ffff03ff0bffff01ff02ffff03ffff09ff05ff1380ffff01ff0101ffff01ff02ff26ffff04ff02ffff04ff05ffff04ff1bff808080808080ff0180ff8080ff0180ff04ffff0101ffff04ffff04ff24ffff04ff05ff808080ffff04ffff04ff30ffff04ff17ffff04ff0bff80808080ff80808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ffff02ff7effff04ff02ffff04ff05ffff04ff07ff8080808080ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff7effff04ff02ffff04ff09ffff04ff0bff8080808080ffff02ff7effff04ff02ffff04ff0dffff04ff0bff808080808080ffff01ff02ffff03ffff02ff26ffff04ff02ffff04ff05ffff04ff0bff8080808080ffff0105ffff01ff0bffff0101ff058080ff018080ff0180ff018080

View File

@ -1 +1 @@
5cee7b4783e96d5d6fa6d365d373c8d536e8908cb8fd5ad893b86ac5fcfab405
9396a2ddf3480e0f141ce40c0277c8715ad72ff9985f606c7b4f6ebbd370e3b6

View File

@ -13,6 +13,6 @@
)
)
(c (list AGG_SIG public_key (sha256tree1 conditions)) conditions)
(c (list AGG_SIG_ME public_key (sha256tree1 conditions)) conditions)
)

View File

@ -1 +1 @@
ff02ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff0bff80808080ff80808080ff0b80ffff04ffff01ff31ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080
ff02ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff0bff80808080ff80808080ff0b80ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080

View File

@ -1 +1 @@
b11d23f3534638ef255337871cedca9e6fc60d4ed42bdb627c16323b659772c1
0ff94726f1a8dea5c3f70d3121945190778d3b2b3fcda3735a1f290977e98341

View File

@ -54,7 +54,7 @@
(defun add_aggsig (public_key_list hash delegated_puzzle solution)
(if public_key_list
(c (list AGG_SIG (f public_key_list) hash)
(c (list AGG_SIG_UNSAFE (f public_key_list) hash)
(add_aggsig (r public_key_list) hash delegated_puzzle solution)
)
(a delegated_puzzle solution)

View File

@ -6,23 +6,27 @@ def make_create_coin_condition(puzzle_hash, amount):
def make_assert_aggsig_condition(pubkey):
return [ConditionOpcode.AGG_SIG, pubkey]
return [ConditionOpcode.AGG_SIG_UNSAFE, pubkey]
def make_assert_my_coin_id_condition(coin_name):
return [ConditionOpcode.ASSERT_MY_COIN_ID, coin_name]
def make_assert_height_now_exceeds_condition(block_index):
return [ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS, block_index]
def make_assert_absolute_height_exceeds_condition(block_index):
return [ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, block_index]
def make_assert_height_age_exceeds_condition(block_index):
return [ConditionOpcode.ASSERT_HEIGHT_AGE_EXCEEDS, block_index]
def make_assert_relative_height_exceeds_condition(block_index):
return [ConditionOpcode.ASSERT_HEIGHT_RELATIVE, block_index]
def make_assert_seconds_now_exceeds_condition(time):
return [ConditionOpcode.ASSERT_SECONDS_NOW_EXCEEDS, time]
def make_assert_absolute_seconds_exceeds_condition(time):
return [ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, time]
def make_assert_relative_seconds_exceeds_condition(time):
return [ConditionOpcode.ASSERT_SECONDS_RELATIVE, time]
def make_reserve_fee_condition(fee):

View File

@ -18,7 +18,7 @@
(sha256 1 tree)))
(defun-inline aggsig-solution-with-key (key)
(list AGG_SIG key (sha256tree (c mode args)))
(list AGG_SIG_UNSAFE key (sha256tree (c mode args)))
)
(defmacro assert items
@ -65,7 +65,7 @@
(defun generate-block-age-condition (min_block_time outgoing_amount rate_amount interval_time)
(assert (>= (* min_block_time rate_amount)
(* outgoing_amount interval_time))
(list ASSERT_HEIGHT_AGE_EXCEEDS min_block_time)))
(list ASSERT_HEIGHT_RELATIVE min_block_time)))
(defun create-change (my_puzzlehash my_amount outgoing_amount fee)
(list CREATE_COIN my_puzzlehash (- my_amount (+ outgoing_amount fee))))

View File

@ -23,7 +23,7 @@ from chia.wallet.puzzles.puzzle_utils import (
make_assert_coin_announcement,
make_assert_puzzle_announcement,
make_assert_my_coin_id_condition,
make_assert_seconds_now_exceeds_condition,
make_assert_absolute_seconds_exceeds_condition,
make_create_coin_announcement,
make_create_puzzle_announcement,
make_create_coin_condition,
@ -202,7 +202,7 @@ class Wallet:
for primary in primaries:
condition_list.append(make_create_coin_condition(primary["puzzlehash"], primary["amount"]))
if min_time > 0:
condition_list.append(make_assert_seconds_now_exceeds_condition(min_time))
condition_list.append(make_assert_absolute_seconds_exceeds_condition(min_time))
if me:
condition_list.append(make_assert_my_coin_id_condition(me["id"]))
if fee:

View File

@ -706,7 +706,7 @@ class TestBlockchainTransactions:
assert err is None
@pytest.mark.asyncio
async def test_assert_block_index_exceeds(self, two_nodes):
async def test_assert_height_absolute(self, two_nodes):
num_blocks = 10
wallet_a = WALLET_A
coinbase_puzzlehash = WALLET_A_PUZZLE_HASHES[0]
@ -730,7 +730,7 @@ class TestBlockchainTransactions:
spend_coin_block_1 = coin
# This condition requires block1 coinbase to be spent after index 10
block1_cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS, [int_to_bytes(10)])
block1_cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, [int_to_bytes(10)])
block1_dic = {block1_cvp.opcode: [block1_cvp]}
block1_spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, spend_coin_block_1, block1_dic
@ -749,7 +749,7 @@ class TestBlockchainTransactions:
# Try to validate that block at index 10
res, err, _ = await full_node_1.blockchain.receive_block(invalid_new_blocks[-1])
assert res == ReceiveBlockResult.INVALID_BLOCK
assert err == Err.ASSERT_HEIGHT_NOW_EXCEEDS_FAILED
assert err == Err.ASSERT_HEIGHT_ABSOLUTE_FAILED
new_blocks = bt.get_consecutive_blocks(
1,
@ -773,7 +773,7 @@ class TestBlockchainTransactions:
assert res == ReceiveBlockResult.NEW_PEAK
@pytest.mark.asyncio
async def test_assert_block_age_exceeds(self, two_nodes):
async def test_assert_height_relative(self, two_nodes):
num_blocks = 11
wallet_a = WALLET_A
coinbase_puzzlehash = WALLET_A_PUZZLE_HASHES[0]
@ -799,7 +799,7 @@ class TestBlockchainTransactions:
# This condition requires block1 coinbase to be spent after index 11
# This condition requires block1 coinbase to be spent more than 10 block after it was farmed
# block index has to be greater than (2 + 9 = 11)
block1_cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_AGE_EXCEEDS, [int_to_bytes(9)])
block1_cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_RELATIVE, [int_to_bytes(9)])
block1_dic = {block1_cvp.opcode: [block1_cvp]}
block1_spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, spend_coin_block_1, block1_dic
@ -818,7 +818,7 @@ class TestBlockchainTransactions:
# Try to validate that block at index 11
res, err, _ = await full_node_1.blockchain.receive_block(invalid_new_blocks[-1])
assert res == ReceiveBlockResult.INVALID_BLOCK
assert err == Err.ASSERT_HEIGHT_AGE_EXCEEDS_FAILED
assert err == Err.ASSERT_HEIGHT_RELATIVE_FAILED
new_blocks = bt.get_consecutive_blocks(
1,
@ -842,7 +842,67 @@ class TestBlockchainTransactions:
assert res == ReceiveBlockResult.NEW_PEAK
@pytest.mark.asyncio
async def test_assert_time_exceeds(self, two_nodes):
async def test_assert_seconds_relative(self, two_nodes):
num_blocks = 10
wallet_a = WALLET_A
coinbase_puzzlehash = WALLET_A_PUZZLE_HASHES[0]
receiver_puzzlehash = BURN_PUZZLE_HASH
# Farm blocks
blocks = bt.get_consecutive_blocks(
num_blocks, farmer_reward_puzzle_hash=coinbase_puzzlehash, guarantee_transaction_block=True
)
full_node_api_1, full_node_api_2, server_1, server_2 = two_nodes
full_node_1 = full_node_api_1.full_node
for block in blocks:
await full_node_api_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
# Coinbase that gets spent
block1 = blocks[2]
spend_coin_block_1 = None
for coin in list(block1.get_included_reward_coins()):
if coin.puzzle_hash == coinbase_puzzlehash:
spend_coin_block_1 = coin
# This condition requires block1 coinbase to be spent 300 seconds after coin creation
block1_cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_RELATIVE, [int_to_bytes(300)])
block1_dic = {block1_cvp.opcode: [block1_cvp]}
block1_spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, spend_coin_block_1, block1_dic
)
# program that will be sent to early
assert block1_spend_bundle is not None
invalid_new_blocks = bt.get_consecutive_blocks(
1,
blocks,
farmer_reward_puzzle_hash=coinbase_puzzlehash,
transaction_data=block1_spend_bundle,
time_per_block=20,
guarantee_transaction_block=True,
)
# Try to validate that block before 300 sec
res, err, _ = await full_node_1.blockchain.receive_block(invalid_new_blocks[-1])
assert res == ReceiveBlockResult.INVALID_BLOCK
assert err == Err.ASSERT_SECONDS_RELATIVE_FAILED
valid_new_blocks = bt.get_consecutive_blocks(
1,
blocks,
farmer_reward_puzzle_hash=coinbase_puzzlehash,
transaction_data=block1_spend_bundle,
guarantee_transaction_block=True,
time_per_block=301,
)
res, err, _ = await full_node_1.blockchain.receive_block(valid_new_blocks[-1])
assert err is None
assert res == ReceiveBlockResult.NEW_PEAK
@pytest.mark.asyncio
async def test_assert_seconds_absolute(self, two_nodes):
num_blocks = 10
wallet_a = WALLET_A
@ -868,7 +928,7 @@ class TestBlockchainTransactions:
# This condition requires block1 coinbase to be spent after 30 seconds from now
current_time_plus3 = uint64(blocks[-1].foliage_transaction_block.timestamp + 30)
block1_cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_NOW_EXCEEDS, [int_to_bytes(current_time_plus3)])
block1_cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, [int_to_bytes(current_time_plus3)])
block1_dic = {block1_cvp.opcode: [block1_cvp]}
block1_spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, spend_coin_block_1, block1_dic
@ -885,10 +945,10 @@ class TestBlockchainTransactions:
guarantee_transaction_block=True,
)
# Try to validate that block before 3 sec
# Try to validate that block before 30 sec
res, err, _ = await full_node_1.blockchain.receive_block(invalid_new_blocks[-1])
assert res == ReceiveBlockResult.INVALID_BLOCK
assert err == Err.ASSERT_SECONDS_NOW_EXCEEDS_FAILED
assert err == Err.ASSERT_SECONDS_ABSOLUTE_FAILED
valid_new_blocks = bt.get_consecutive_blocks(
1,

View File

@ -222,10 +222,10 @@ class TestMempoolManager:
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
cvp = ConditionWithArgs(
ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS,
ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE,
[uint64(start_height + 5).to_bytes(4, "big")],
)
dic = {ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS: [cvp]}
dic = {ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
@ -256,8 +256,8 @@ class TestMempoolManager:
await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block))
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS, [uint64(1).to_bytes(4, "big")])
dic = {ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS: [cvp]}
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, [uint64(1).to_bytes(4, "big")])
dic = {ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
@ -286,7 +286,7 @@ class TestMempoolManager:
await time_out_assert(60, node_height_at_least, True, full_node_1, 2)
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_AGE_EXCEEDS, [uint64(5).to_bytes(4, "big")])
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_RELATIVE, [uint64(5).to_bytes(4, "big")])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
@ -318,7 +318,7 @@ class TestMempoolManager:
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 4)
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_AGE_EXCEEDS, [uint64(1).to_bytes(4, "big")])
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_HEIGHT_RELATIVE, [uint64(1).to_bytes(4, "big")])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-2].get_included_reward_coins())[0], dic)
@ -423,7 +423,7 @@ class TestMempoolManager:
time_now = uint64(int(time() * 1000))
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_NOW_EXCEEDS, [time_now.to_bytes(8, "big")])
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, [time_now.to_bytes(8, "big")])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
@ -459,7 +459,7 @@ class TestMempoolManager:
time_now = uint64(int(time() * 1000))
time_now_plus_3 = time_now + 3000
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_NOW_EXCEEDS, [time_now_plus_3.to_bytes(8, "big")])
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, [time_now_plus_3.to_bytes(8, "big")])
dic = {cvp.opcode: [cvp]}
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)