More full node tests
This commit is contained in:
parent
4b98c3706d
commit
c90aa0984d
|
@ -752,8 +752,6 @@ class FullNode:
|
|||
A proof of time, received by a peer full node. If we have the rest of the block,
|
||||
we can complete it. Otherwise, we just verify and propagate the proof.
|
||||
"""
|
||||
finish_block: bool = False
|
||||
propagate_proof: bool = False
|
||||
if (
|
||||
self.store.get_unfinished_block(
|
||||
(
|
||||
|
@ -763,33 +761,26 @@ class FullNode:
|
|||
)
|
||||
is not None
|
||||
):
|
||||
finish_block = True
|
||||
elif respond_proof_of_time.proof.is_valid(constants["DISCRIMINANT_SIZE_BITS"]):
|
||||
propagate_proof = True
|
||||
|
||||
if finish_block or propagate_proof:
|
||||
height: Optional[uint32] = self.store.get_proof_of_time_heights(
|
||||
(
|
||||
respond_proof_of_time.proof.challenge_hash,
|
||||
respond_proof_of_time.proof.number_of_iterations,
|
||||
)
|
||||
)
|
||||
if height is None:
|
||||
return
|
||||
yield OutboundMessage(
|
||||
NodeType.FULL_NODE,
|
||||
Message(
|
||||
"new_proof_of_time",
|
||||
full_node_protocol.NewProofOfTime(
|
||||
height,
|
||||
respond_proof_of_time.proof.challenge_hash,
|
||||
respond_proof_of_time.proof.number_of_iterations,
|
||||
if height is not None:
|
||||
yield OutboundMessage(
|
||||
NodeType.FULL_NODE,
|
||||
Message(
|
||||
"new_proof_of_time",
|
||||
full_node_protocol.NewProofOfTime(
|
||||
height,
|
||||
respond_proof_of_time.proof.challenge_hash,
|
||||
respond_proof_of_time.proof.number_of_iterations,
|
||||
),
|
||||
),
|
||||
),
|
||||
Delivery.BROADCAST_TO_OTHERS,
|
||||
)
|
||||
Delivery.BROADCAST_TO_OTHERS,
|
||||
)
|
||||
|
||||
if finish_block:
|
||||
request = timelord_protocol.ProofOfTimeFinished(respond_proof_of_time.proof)
|
||||
async for msg in self.proof_of_time_finished(request):
|
||||
yield msg
|
||||
|
@ -931,13 +922,23 @@ class FullNode:
|
|||
)
|
||||
if prev_block is not None:
|
||||
challenge = self.blockchain.get_challenge(prev_block)
|
||||
if (
|
||||
self.store.get_unfinished_block(
|
||||
(challenge, self.new_unfinished_block.iterations_needed)
|
||||
)
|
||||
is not None
|
||||
):
|
||||
return
|
||||
if challenge is not None:
|
||||
if (
|
||||
self.store.get_unfinished_block(
|
||||
(
|
||||
challenge.get_hash(),
|
||||
new_unfinished_block.number_of_iterations,
|
||||
)
|
||||
)
|
||||
is not None
|
||||
):
|
||||
return
|
||||
assert challenge is not None
|
||||
print(self.store.unfinished_blocks.keys())
|
||||
print(
|
||||
"It's none..",
|
||||
(challenge.get_hash(), new_unfinished_block.number_of_iterations),
|
||||
)
|
||||
yield OutboundMessage(
|
||||
NodeType.FULL_NODE,
|
||||
Message(
|
||||
|
|
|
@ -82,7 +82,7 @@ class RespondProofOfTime:
|
|||
@cbor_message
|
||||
class RejectProofOfTimeRequest:
|
||||
challenge_hash: bytes32
|
||||
iterations: uint64
|
||||
number_of_iterations: uint64
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
|
@ -111,14 +111,14 @@ class RespondCompactProofOfTime:
|
|||
@cbor_message
|
||||
class RejectCompactProofOfTimeRequest:
|
||||
challenge_hash: bytes32
|
||||
iterations: uint64
|
||||
number_of_iterations: uint64
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@cbor_message
|
||||
class NewUnfinishedBlock:
|
||||
previous_header_hash: bytes32
|
||||
iterations: uint64
|
||||
number_of_iterations: uint64
|
||||
new_header_hash: bytes32
|
||||
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ from secrets import token_bytes
|
|||
|
||||
from src.protocols import full_node_protocol as fnp
|
||||
from src.types.peer_info import PeerInfo
|
||||
from src.types.full_block import FullBlock
|
||||
from src.types.hashable.SpendBundle import SpendBundle
|
||||
from src.util.bundle_tools import best_solution_program
|
||||
from src.util.ints import uint16, uint32, uint64
|
||||
|
@ -234,3 +235,261 @@ class TestFullNode:
|
|||
async def test_new_pot(self, two_nodes, wallet_blocks):
|
||||
full_node_1, full_node_2, server_1, server_2 = two_nodes
|
||||
wallet_a, wallet_receiver, blocks = wallet_blocks
|
||||
|
||||
no_unf_block = fnp.NewProofOfTime(uint32(5), bytes(32 * [1]), uint64(124512))
|
||||
assert len([x async for x in full_node_1.new_proof_of_time(no_unf_block)]) == 0
|
||||
|
||||
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
|
||||
blocks_new = bt.get_consecutive_blocks(
|
||||
test_constants,
|
||||
1,
|
||||
blocks[:-1],
|
||||
10,
|
||||
reward_puzzlehash=coinbase_puzzlehash,
|
||||
seed=b"1212412",
|
||||
)
|
||||
unf_block = FullBlock(
|
||||
blocks_new[-1].proof_of_space,
|
||||
None,
|
||||
blocks_new[-1].header,
|
||||
blocks_new[-1].body,
|
||||
)
|
||||
unf_block_req = fnp.RespondUnfinishedBlock(unf_block)
|
||||
|
||||
res = [x async for x in full_node_1.respond_unfinished_block(unf_block_req)]
|
||||
|
||||
dont_have = fnp.NewProofOfTime(
|
||||
unf_block.height,
|
||||
unf_block.proof_of_space.challenge_hash,
|
||||
res[0].message.data.iterations_needed,
|
||||
)
|
||||
assert len([x async for x in full_node_1.new_proof_of_time(dont_have)]) == 1
|
||||
|
||||
[x async for x in full_node_1.respond_block(fnp.RespondBlock(blocks_new[-1]))]
|
||||
|
||||
already_have = fnp.NewProofOfTime(
|
||||
unf_block.height,
|
||||
unf_block.proof_of_space.challenge_hash,
|
||||
res[0].message.data.iterations_needed,
|
||||
)
|
||||
assert len([x async for x in full_node_1.new_proof_of_time(already_have)]) == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_request_pot(self, two_nodes, wallet_blocks):
|
||||
full_node_1, full_node_2, server_1, server_2 = two_nodes
|
||||
wallet_a, wallet_receiver, blocks = wallet_blocks
|
||||
|
||||
request = fnp.RequestProofOfTime(
|
||||
blocks[3].height,
|
||||
blocks[3].proof_of_space.challenge_hash,
|
||||
blocks[3].proof_of_time.number_of_iterations,
|
||||
)
|
||||
res = [x async for x in full_node_1.request_proof_of_time(request)]
|
||||
assert len(res) == 1
|
||||
assert res[0].message.data.proof == blocks[3].proof_of_time
|
||||
|
||||
request_bad = fnp.RequestProofOfTime(
|
||||
blocks[3].height,
|
||||
blocks[3].proof_of_space.challenge_hash,
|
||||
blocks[3].proof_of_time.number_of_iterations + 1,
|
||||
)
|
||||
res_bad = [x async for x in full_node_1.request_proof_of_time(request_bad)]
|
||||
assert len(res_bad) == 1
|
||||
assert isinstance(res_bad[0].message.data, fnp.RejectProofOfTimeRequest)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_respond_pot(self, two_nodes, wallet_blocks):
|
||||
full_node_1, full_node_2, server_1, server_2 = two_nodes
|
||||
wallet_a, wallet_receiver, blocks = wallet_blocks
|
||||
|
||||
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
|
||||
blocks_list = [(await full_node_1.blockchain.get_full_tips())[0]]
|
||||
while blocks_list[0].height != 0:
|
||||
b = await full_node_1.store.get_block(blocks_list[0].prev_header_hash)
|
||||
blocks_list.insert(0, b)
|
||||
|
||||
blocks_new = bt.get_consecutive_blocks(
|
||||
test_constants,
|
||||
1,
|
||||
blocks_list,
|
||||
10,
|
||||
reward_puzzlehash=coinbase_puzzlehash,
|
||||
seed=b"another seed",
|
||||
)
|
||||
assert blocks_new[-1].proof_of_time is not None
|
||||
new_pot = fnp.NewProofOfTime(
|
||||
blocks_new[-1].height,
|
||||
blocks_new[-1].proof_of_space.challenge_hash,
|
||||
blocks_new[-1].proof_of_time.number_of_iterations,
|
||||
)
|
||||
[x async for x in full_node_1.new_proof_of_time(new_pot)]
|
||||
|
||||
# Don't have unfinished block
|
||||
respond_pot = fnp.RespondProofOfTime(blocks_new[-1].proof_of_time)
|
||||
res = [x async for x in full_node_1.respond_proof_of_time(respond_pot)]
|
||||
assert len(res) == 0
|
||||
|
||||
unf_block = FullBlock(
|
||||
blocks_new[-1].proof_of_space,
|
||||
None,
|
||||
blocks_new[-1].header,
|
||||
blocks_new[-1].body,
|
||||
)
|
||||
unf_block_req = fnp.RespondUnfinishedBlock(unf_block)
|
||||
[x async for x in full_node_1.respond_unfinished_block(unf_block_req)]
|
||||
|
||||
# Have unfinished block, finish
|
||||
assert blocks_new[-1].proof_of_time is not None
|
||||
respond_pot = fnp.RespondProofOfTime(blocks_new[-1].proof_of_time)
|
||||
res = [x async for x in full_node_1.respond_proof_of_time(respond_pot)]
|
||||
assert len(res) == 4
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_new_unfinished(self, two_nodes, wallet_blocks):
|
||||
full_node_1, full_node_2, server_1, server_2 = two_nodes
|
||||
wallet_a, wallet_receiver, blocks = wallet_blocks
|
||||
|
||||
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
|
||||
blocks_list = [(await full_node_1.blockchain.get_full_tips())[0]]
|
||||
while blocks_list[0].height != 0:
|
||||
b = await full_node_1.store.get_block(blocks_list[0].prev_header_hash)
|
||||
blocks_list.insert(0, b)
|
||||
|
||||
blocks_new = bt.get_consecutive_blocks(
|
||||
test_constants,
|
||||
1,
|
||||
blocks_list,
|
||||
10,
|
||||
reward_puzzlehash=coinbase_puzzlehash,
|
||||
seed=b"another seed 2",
|
||||
)
|
||||
assert blocks_new[-1].proof_of_time is not None
|
||||
assert blocks_new[-2].proof_of_time is not None
|
||||
already_have = fnp.NewUnfinishedBlock(
|
||||
blocks_new[-2].prev_header_hash,
|
||||
blocks_new[-2].proof_of_time.number_of_iterations,
|
||||
blocks_new[-2].header_hash,
|
||||
)
|
||||
assert (
|
||||
len([x async for x in full_node_1.new_unfinished_block(already_have)]) == 0
|
||||
)
|
||||
|
||||
bad_prev = fnp.NewUnfinishedBlock(
|
||||
blocks_new[-1].header_hash,
|
||||
blocks_new[-1].proof_of_time.number_of_iterations,
|
||||
blocks_new[-1].header_hash,
|
||||
)
|
||||
|
||||
assert len([x async for x in full_node_1.new_unfinished_block(bad_prev)]) == 0
|
||||
good = fnp.NewUnfinishedBlock(
|
||||
blocks_new[-1].prev_header_hash,
|
||||
blocks_new[-1].proof_of_time.number_of_iterations,
|
||||
blocks_new[-1].header_hash,
|
||||
)
|
||||
assert len([x async for x in full_node_1.new_unfinished_block(good)]) == 1
|
||||
|
||||
unf_block = FullBlock(
|
||||
blocks_new[-1].proof_of_space,
|
||||
None,
|
||||
blocks_new[-1].header,
|
||||
blocks_new[-1].body,
|
||||
)
|
||||
unf_block_req = fnp.RespondUnfinishedBlock(unf_block)
|
||||
[x async for x in full_node_1.respond_unfinished_block(unf_block_req)]
|
||||
|
||||
assert len([x async for x in full_node_1.new_unfinished_block(good)]) == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_request_unfinished(self, two_nodes, wallet_blocks):
|
||||
full_node_1, full_node_2, server_1, server_2 = two_nodes
|
||||
wallet_a, wallet_receiver, blocks = wallet_blocks
|
||||
|
||||
coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
|
||||
blocks_list = [(await full_node_1.blockchain.get_full_tips())[0]]
|
||||
while blocks_list[0].height != 0:
|
||||
b = await full_node_1.store.get_block(blocks_list[0].prev_header_hash)
|
||||
blocks_list.insert(0, b)
|
||||
|
||||
blocks_new = bt.get_consecutive_blocks(
|
||||
test_constants,
|
||||
1,
|
||||
blocks_list,
|
||||
10,
|
||||
reward_puzzlehash=coinbase_puzzlehash,
|
||||
seed=b"another seed 3",
|
||||
)
|
||||
unf_block = FullBlock(
|
||||
blocks_new[-1].proof_of_space,
|
||||
None,
|
||||
blocks_new[-1].header,
|
||||
blocks_new[-1].body,
|
||||
)
|
||||
unf_block_req = fnp.RespondUnfinishedBlock(unf_block)
|
||||
|
||||
# Don't have
|
||||
req = fnp.RequestUnfinishedBlock(unf_block.header_hash)
|
||||
res = [x async for x in full_node_1.request_unfinished_block(req)]
|
||||
assert len(res) == 1
|
||||
assert res[0].message.data == fnp.RejectUnfinishedBlockRequest(
|
||||
unf_block.header_hash
|
||||
)
|
||||
|
||||
# Have unfinished block
|
||||
[x async for x in full_node_1.respond_unfinished_block(unf_block_req)]
|
||||
res = [x async for x in full_node_1.request_unfinished_block(req)]
|
||||
assert len(res) == 1
|
||||
assert res[0].message.data == fnp.RespondUnfinishedBlock(unf_block)
|
||||
|
||||
# Have full block (genesis in this case)
|
||||
req = fnp.RequestUnfinishedBlock(blocks_new[0].header_hash)
|
||||
res = [x async for x in full_node_1.request_unfinished_block(req)]
|
||||
assert len(res) == 1
|
||||
assert res[0].message.data.block.header_hash == blocks_new[0].header_hash
|
||||
|
||||
# @pytest.mark.asyncio
|
||||
# async def test_respond_unfinished(self, two_nodes, wallet_blocks):
|
||||
# full_node_1, full_node_2, server_1, server_2 = two_nodes
|
||||
# wallet_a, wallet_receiver, blocks = wallet_blocks
|
||||
|
||||
# coinbase_puzzlehash = wallet_a.get_new_puzzlehash()
|
||||
# blocks_list = [(await full_node_1.blockchain.get_full_tips())[0]]
|
||||
# while blocks_list[0].height != 0:
|
||||
# b = await full_node_1.store.get_block(blocks_list[0].prev_header_hash)
|
||||
# blocks_list.insert(0, b)
|
||||
|
||||
# candidates = []
|
||||
# for i in range(50):
|
||||
# blocks_new = bt.get_consecutive_blocks(
|
||||
# test_constants,
|
||||
# 1,
|
||||
# blocks_list,
|
||||
# 10,
|
||||
# reward_puzzlehash=coinbase_puzzlehash,
|
||||
# seed=b"another seed 4",
|
||||
# )
|
||||
# candidates.append(blocks_new[-1])
|
||||
|
||||
# print([c.proof_of_time.number_of_iterations for c in candidates])
|
||||
|
||||
# unf_block = FullBlock(
|
||||
# candidates[0].proof_of_space,
|
||||
# None,
|
||||
# candidates[0].header,
|
||||
# candidates[0].body,
|
||||
# )
|
||||
# unf_block_not_child = FullBlock(
|
||||
# candidates[0].proof_of_space,
|
||||
# None,
|
||||
# candidates[0].header,
|
||||
# candidates[0].body,
|
||||
# )
|
||||
|
||||
# unf_block_req_bad = fnp.RespondUnfinishedBlock(unf_block_not_child)
|
||||
# assert len([x async for x in full_node_1.respond_unfinished_block(unf_block_req_bad)]) == 0
|
||||
|
||||
# Already seen
|
||||
# Slow block should delay prop
|
||||
# Highest height should propagate
|
||||
# Slow equal height should not
|
||||
# Fastest equal height should
|
||||
# Don't propagate at old height
|
||||
|
|
|
@ -43,7 +43,7 @@ class WalletTool:
|
|||
self.extended_secret_key = ExtendedPrivateKey.from_seed(self.seed)
|
||||
self.generator_lookups: Dict = {}
|
||||
self.name = "MyChiaWallet"
|
||||
self.puzzle_pk_cache = {}
|
||||
self.puzzle_pk_cache: Dict = {}
|
||||
|
||||
def get_next_public_key(self):
|
||||
pubkey = self.extended_secret_key.public_child(
|
||||
|
|
Loading…
Reference in New Issue