Blockchain timestamps fix (#2302)
* incomplete push for debugging * block timestamp in mempool * rename * farm tx block Co-authored-by: matt <matt@chia.net>
This commit is contained in:
parent
572110b7df
commit
328e4cd276
|
@ -71,38 +71,36 @@ def mempool_assert_relative_block_height_exceeds(
|
|||
return None
|
||||
|
||||
|
||||
def mempool_assert_absolute_time_exceeds(
|
||||
condition: ConditionWithArgs, timestamp: Optional[uint64] = None
|
||||
) -> Optional[Err]:
|
||||
def mempool_assert_absolute_time_exceeds(condition: ConditionWithArgs, timestamp: uint64) -> Optional[Err]:
|
||||
"""
|
||||
Check if the current time in millis exceeds the time specified by condition
|
||||
Check if the current time in seconds exceeds the time specified by condition
|
||||
"""
|
||||
try:
|
||||
expected_mili_time = int_from_bytes(condition.vars[0])
|
||||
expected_seconds = int_from_bytes(condition.vars[0])
|
||||
except ValueError:
|
||||
return Err.INVALID_CONDITION
|
||||
|
||||
if timestamp is None:
|
||||
timestamp = uint64(int(time.time() * 1000))
|
||||
if timestamp < expected_mili_time:
|
||||
timestamp = uint64(int(time.time()))
|
||||
if timestamp < expected_seconds:
|
||||
return Err.ASSERT_SECONDS_ABSOLUTE_FAILED
|
||||
return None
|
||||
|
||||
|
||||
def mempool_assert_relative_time_exceeds(
|
||||
condition: ConditionWithArgs, unspent: CoinRecord, timestamp: Optional[uint64] = None
|
||||
condition: ConditionWithArgs, unspent: CoinRecord, timestamp: uint64
|
||||
) -> Optional[Err]:
|
||||
"""
|
||||
Check if the current time in millis exceeds the time specified by condition
|
||||
Check if the current time in seconds exceeds the time specified by condition
|
||||
"""
|
||||
try:
|
||||
expected_mili_time = int_from_bytes(condition.vars[0])
|
||||
expected_seconds = int_from_bytes(condition.vars[0])
|
||||
except ValueError:
|
||||
return Err.INVALID_CONDITION
|
||||
|
||||
if timestamp is None:
|
||||
timestamp = uint64(int(time.time() * 1000))
|
||||
if timestamp < expected_mili_time + unspent.timestamp:
|
||||
timestamp = uint64(int(time.time()))
|
||||
if timestamp < expected_seconds + unspent.timestamp:
|
||||
return Err.ASSERT_SECONDS_RELATIVE_FAILED
|
||||
return None
|
||||
|
||||
|
@ -196,7 +194,7 @@ def mempool_check_conditions_dict(
|
|||
puzzle_announcement_names: Set[bytes32],
|
||||
conditions_dict: Dict[ConditionOpcode, List[ConditionWithArgs]],
|
||||
prev_transaction_block_height: uint32,
|
||||
timestamp: Optional[uint64] = None,
|
||||
timestamp: uint64,
|
||||
) -> Optional[Err]:
|
||||
"""
|
||||
Check all conditions against current state.
|
||||
|
|
|
@ -274,13 +274,14 @@ class MempoolManager:
|
|||
elif name in additions_dict:
|
||||
removal_coin = additions_dict[name]
|
||||
# TODO(straya): what timestamp to use here?
|
||||
assert self.peak.timestamp is not None
|
||||
removal_record = CoinRecord(
|
||||
removal_coin,
|
||||
uint32(self.peak.height + 1), # In mempool, so will be included in next height
|
||||
uint32(0),
|
||||
False,
|
||||
False,
|
||||
uint64(int(time.time())),
|
||||
uint64(self.peak.timestamp + 1),
|
||||
)
|
||||
|
||||
assert removal_record is not None
|
||||
|
@ -367,12 +368,14 @@ class MempoolManager:
|
|||
chialisp_height = (
|
||||
self.peak.prev_transaction_block_height if not self.peak.is_transaction_block else self.peak.height
|
||||
)
|
||||
assert self.peak.timestamp is not None
|
||||
error = mempool_check_conditions_dict(
|
||||
coin_record,
|
||||
coin_announcements_in_spend,
|
||||
puzzle_announcements_in_spend,
|
||||
npc.condition_dict,
|
||||
uint32(chialisp_height),
|
||||
self.peak.timestamp,
|
||||
)
|
||||
|
||||
if error:
|
||||
|
@ -465,9 +468,12 @@ class MempoolManager:
|
|||
"""
|
||||
if new_peak is None:
|
||||
return []
|
||||
if new_peak.is_transaction_block is False:
|
||||
return []
|
||||
if self.peak == new_peak:
|
||||
return []
|
||||
if int(time.time()) <= self.constants.INITIAL_FREEZE_END_TIMESTAMP:
|
||||
assert new_peak.timestamp is not None
|
||||
if new_peak.timestamp <= self.constants.INITIAL_FREEZE_END_TIMESTAMP:
|
||||
return []
|
||||
|
||||
self.peak = new_peak
|
||||
|
|
|
@ -7,6 +7,7 @@ import pytest
|
|||
|
||||
from chia.full_node.mempool import Mempool
|
||||
from chia.protocols import full_node_protocol
|
||||
from chia.simulator.simulator_protocol import FarmNewBlockProtocol
|
||||
from chia.types.announcement import Announcement
|
||||
from chia.types.blockchain_format.coin import Coin
|
||||
from chia.types.coin_solution import CoinSolution
|
||||
|
@ -458,7 +459,7 @@ class TestMempoolManager:
|
|||
|
||||
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
|
||||
|
||||
time_now = uint64(int(time() * 1000))
|
||||
time_now = uint64(int(time()))
|
||||
|
||||
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, [time_now.to_bytes(8, "big")])
|
||||
dic = {cvp.opcode: [cvp]}
|
||||
|
@ -474,7 +475,7 @@ class TestMempoolManager:
|
|||
assert sb1 is spend_bundle1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_assert_time_exceeds_both_cases(self, two_nodes):
|
||||
async def test_assert_time_relative_exceeds(self, two_nodes):
|
||||
reward_ph = WALLET_A.get_new_puzzlehash()
|
||||
full_node_1, full_node_2, server_1, server_2 = two_nodes
|
||||
blocks = await full_node_1.get_all_full_blocks()
|
||||
|
@ -493,20 +494,22 @@ class TestMempoolManager:
|
|||
|
||||
await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3)
|
||||
|
||||
time_now = uint64(int(time() * 1000))
|
||||
time_now_plus_3 = time_now + 3000
|
||||
time_relative = uint64(3)
|
||||
|
||||
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, [time_now_plus_3.to_bytes(8, "big")])
|
||||
cvp = ConditionWithArgs(ConditionOpcode.ASSERT_SECONDS_RELATIVE, [time_relative.to_bytes(8, "big")])
|
||||
dic = {cvp.opcode: [cvp]}
|
||||
|
||||
spend_bundle1 = generate_test_spend_bundle(list(blocks[-1].get_included_reward_coins())[0], dic)
|
||||
|
||||
assert spend_bundle1 is not None
|
||||
|
||||
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
|
||||
await full_node_1.respond_transaction(tx1, peer)
|
||||
|
||||
# Sleep so that 3 sec passes
|
||||
await asyncio.sleep(3)
|
||||
sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name())
|
||||
assert sb1 is None
|
||||
|
||||
for i in range(0, 4):
|
||||
await full_node_1.farm_new_transaction_block(FarmNewBlockProtocol(32 * b"0"))
|
||||
|
||||
tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1)
|
||||
await full_node_1.respond_transaction(tx2, peer)
|
||||
|
|
|
@ -118,8 +118,7 @@ class TestWalletRpc:
|
|||
assert (await client.get_wallet_balance("1"))["confirmed_wallet_balance"] == initial_funds
|
||||
|
||||
for i in range(0, 5):
|
||||
await client.farm_block(encode_puzzle_hash(ph_2, "xch"))
|
||||
await asyncio.sleep(0.5)
|
||||
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_2))
|
||||
|
||||
async def eventual_balance():
|
||||
return (await client.get_wallet_balance("1"))["confirmed_wallet_balance"]
|
||||
|
|
Loading…
Reference in New Issue