Merge
This commit is contained in:
commit
a22e606f75
|
@ -5,6 +5,8 @@ __pycache__/
|
|||
|
||||
# C extensions
|
||||
*.so
|
||||
**/*.o
|
||||
.DS_Store
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
|
|
|
@ -8,6 +8,11 @@ Python 3.7 is used for this project.
|
|||
sudo apt-get install build-essential cmake python3-dev --no-install-recommends
|
||||
|
||||
git submodule update --init --recursive
|
||||
|
||||
cd lib/chiavdf
|
||||
# Install libgmp, libboost, and libflint, and then run the following
|
||||
sh install.sh
|
||||
|
||||
python3 -m venv .venv
|
||||
. .venv/bin/activate
|
||||
pip install wheel
|
||||
|
@ -18,6 +23,7 @@ pip install lib/chiapos
|
|||
### Run servers
|
||||
Run the servers in the following order (you can also use ipython):
|
||||
```bash
|
||||
./lib/chiavdf/fast_vdf/vdf 8889
|
||||
python -m src.server.start_plotter
|
||||
python -m src.server.start_timelord
|
||||
python -m src.server.start_farmer
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 28942e66fda6397443aa33c0cb6515d8e8b991e7
|
||||
Subproject commit 6a5570ba4d1b71d8e0e8e3f7e19acb898d601ff5
|
|
@ -361,8 +361,8 @@ class Blockchain:
|
|||
return False
|
||||
|
||||
# 4. Check PoT
|
||||
#TODO(Florin): Change the hardcode of the genesis with new pot format.
|
||||
if not block.trunk_block.proof_of_time.is_valid(self.constants["DISCRIMINANT_SIZE_BITS"]) and not genesis:
|
||||
# TODO(Florin): Change the hardcode of the genesis with new pot format.
|
||||
if not block.trunk_block.proof_of_time.is_valid(self.constants["DISCRIMINANT_SIZE_BITS"]):
|
||||
return False
|
||||
|
||||
if block.body.coinbase.height != block.trunk_block.challenge.height:
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -627,4 +627,3 @@ async def block(block: peer_protocol.Block) -> AsyncGenerator[OutboundMessage, N
|
|||
timelord_request_end = timelord_protocol.ChallengeStart(block.block.trunk_block.proof_of_time.
|
||||
output.challenge_hash)
|
||||
yield OutboundMessage(NodeType.TIMELORD, Message("challenge_end", timelord_request_end), Delivery.BROADCAST)
|
||||
|
||||
|
|
|
@ -197,19 +197,19 @@ async def initialize_pipeline(aiter,
|
|||
handshake_finished_3 = forker.fork(is_active=True)
|
||||
|
||||
# Reads messages one at a time from the TCP connection
|
||||
messages_aiter = join_aiters(parallel_map_aiter(connection_to_message, 100, handshake_finished_1))
|
||||
messages_aiter = join_aiters(parallel_map_aiter(connection_to_message, handshake_finished_1, 100))
|
||||
|
||||
# Handles each message one at a time, and yields responses to send back or broadcast
|
||||
responses_aiter = join_aiters(parallel_map_aiter(
|
||||
partial_func.partial_async_gen(handle_message, api),
|
||||
100, messages_aiter))
|
||||
messages_aiter, 100))
|
||||
|
||||
if on_connect is not None:
|
||||
# Uses a forked aiter, and calls the on_connect function to send some initial messages
|
||||
# as soon as the connection is established
|
||||
|
||||
on_connect_outbound_aiter = join_aiters(parallel_map_aiter(
|
||||
partial_func.partial_async_gen(connection_to_outbound, on_connect), 100, handshake_finished_2))
|
||||
partial_func.partial_async_gen(connection_to_outbound, on_connect), handshake_finished_2, 100))
|
||||
|
||||
responses_aiter = join_aiters(iter_to_aiter([responses_aiter, on_connect_outbound_aiter]))
|
||||
if outbound_aiter is not None:
|
||||
|
@ -220,7 +220,7 @@ async def initialize_pipeline(aiter,
|
|||
|
||||
# For each outbound message, replicate for each peer that we need to send to
|
||||
expanded_messages_aiter = join_aiters(parallel_map_aiter(
|
||||
expand_outbound_messages, 100, responses_aiter))
|
||||
expand_outbound_messages, responses_aiter, 100))
|
||||
|
||||
# This will run forever. Sends each message through the TCP connection, using the
|
||||
# length encoding and CBOR serialization
|
||||
|
|
|
@ -7,6 +7,7 @@ from src import timelord
|
|||
|
||||
logging.basicConfig(format='Timelord %(name)-25s: %(levelname)-20s %(message)s', level=logging.INFO)
|
||||
|
||||
|
||||
async def main():
|
||||
host, port = parse_host_port(timelord)
|
||||
server, _ = await start_chia_server(host, port, timelord, NodeType.FULL_NODE)
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import logging
|
||||
import asyncio
|
||||
import time
|
||||
import io
|
||||
import sys
|
||||
import yaml
|
||||
from asyncio import Lock
|
||||
from typing import Dict
|
||||
from typing import Dict, Optional
|
||||
|
||||
from lib.chiavdf.inkfish.create_discriminant import create_discriminant
|
||||
from lib.chiavdf.inkfish.proof_of_time import check_proof_of_time_nwesolowski
|
||||
|
@ -18,6 +16,7 @@ from src.util.ints import uint8
|
|||
from src.consensus.constants import constants
|
||||
from src.server.outbound_message import OutboundMessage, Delivery, Message, NodeType
|
||||
|
||||
|
||||
class Database:
|
||||
lock: Lock = Lock()
|
||||
free_servers = []
|
||||
|
@ -25,11 +24,13 @@ class Database:
|
|||
active_discriminants: Dict = {}
|
||||
done_discriminants = []
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
config = yaml.safe_load(open("src/config/timelord.yaml", "r"))
|
||||
db = Database()
|
||||
db.free_servers.append(8889)
|
||||
|
||||
|
||||
@api_request
|
||||
async def challenge_start(challenge_start: timelord_protocol.ChallengeStart):
|
||||
"""
|
||||
|
@ -37,7 +38,7 @@ async def challenge_start(challenge_start: timelord_protocol.ChallengeStart):
|
|||
should be started on it. We can generate a classgroup (discriminant), and start
|
||||
a new VDF process here. But we don't know how many iterations to run for, so we run
|
||||
forever.
|
||||
"""
|
||||
"""
|
||||
|
||||
disc: int = create_discriminant(challenge_start.challenge_hash, constants["DISCRIMINANT_SIZE_BITS"])
|
||||
|
||||
|
@ -46,19 +47,19 @@ async def challenge_start(challenge_start: timelord_protocol.ChallengeStart):
|
|||
log.info("This discriminant was already done..")
|
||||
return
|
||||
|
||||
#Wait for a server to become free.
|
||||
port = None
|
||||
# Wait for a server to become free.
|
||||
port: Optional[int] = None
|
||||
while (port is None):
|
||||
async with db.lock:
|
||||
if (len(db.free_servers) != 0):
|
||||
port = db.free_servers[0]
|
||||
db.free_servers = db.free_servers[1:]
|
||||
log.info(f"Discriminant {disc} attached to port {port}.")
|
||||
#Poll until a server becomes free.
|
||||
# Poll until a server becomes free.
|
||||
if (port is None):
|
||||
await asyncio.sleep(3)
|
||||
|
||||
#TODO(Florin): Handle connection failure (attempt another server)
|
||||
|
||||
# TODO(Florin): Handle connection failure (attempt another server)
|
||||
try:
|
||||
reader, writer = await asyncio.open_connection('127.0.0.1', port)
|
||||
except Exception as e:
|
||||
|
@ -70,17 +71,17 @@ async def challenge_start(challenge_start: timelord_protocol.ChallengeStart):
|
|||
|
||||
ok = await reader.readexactly(2)
|
||||
assert(ok.decode() == "OK")
|
||||
|
||||
|
||||
log.info("Got handshake with VDF server.")
|
||||
|
||||
async with db.lock:
|
||||
db.active_discriminants[challenge_start.challenge_hash] = writer
|
||||
|
||||
#Listen to the server until "STOP" is received.
|
||||
while(True):
|
||||
# Listen to the server until "STOP" is received.
|
||||
while True:
|
||||
data = await reader.readexactly(4)
|
||||
if (data.decode() == "STOP"):
|
||||
#Server is now available.
|
||||
# Server is now available.
|
||||
async with db.lock:
|
||||
writer.write(b"ACK")
|
||||
await writer.drain()
|
||||
|
@ -88,7 +89,7 @@ async def challenge_start(challenge_start: timelord_protocol.ChallengeStart):
|
|||
break
|
||||
else:
|
||||
try:
|
||||
#This must be a proof, read the continuation.
|
||||
# This must be a proof, read the continuation.
|
||||
proof = await reader.readexactly(1860)
|
||||
stdout_bytes_io: io.BytesIO = io.BytesIO(bytes.fromhex(data.decode() + proof.decode()))
|
||||
iterations_needed = int.from_bytes(stdout_bytes_io.read(8), "big", signed=True)
|
||||
|
@ -101,13 +102,13 @@ async def challenge_start(challenge_start: timelord_protocol.ChallengeStart):
|
|||
assert check_proof_of_time_nwesolowski(disc, x, proof_blob, iterations_needed, 1024, 2)
|
||||
|
||||
output = ProofOfTimeOutput(challenge_start.challenge_hash,
|
||||
iterations_needed,
|
||||
ClassgroupElement(y.a, y.b))
|
||||
iterations_needed,
|
||||
ClassgroupElement(y.a, y.b))
|
||||
proof_of_time = ProofOfTime(output, config['n_wesolowski'], [uint8(b) for b in proof_bytes])
|
||||
response = timelord_protocol.ProofOfTimeFinished(proof_of_time)
|
||||
|
||||
log.info(f"Got PoT for challenge {challenge_start.challenge_hash}")
|
||||
#async with db.lock:
|
||||
# async with db.lock:
|
||||
# if (challenge_start.challenge_hash in db.solved_discriminants):
|
||||
# log.info("I've already propagated one proof... Ignoring for now...")
|
||||
# continue
|
||||
|
@ -117,7 +118,7 @@ async def challenge_start(challenge_start: timelord_protocol.ChallengeStart):
|
|||
e_to_str = str(e)
|
||||
log.error(f"Socket error: {e_to_str}")
|
||||
|
||||
|
||||
|
||||
@api_request
|
||||
async def challenge_end(challenge_end: timelord_protocol.ChallengeEnd):
|
||||
"""
|
||||
|
@ -126,7 +127,7 @@ async def challenge_end(challenge_end: timelord_protocol.ChallengeEnd):
|
|||
"""
|
||||
async with db.lock:
|
||||
if (challenge_end.challenge_hash in db.done_discriminants):
|
||||
return
|
||||
return
|
||||
if (challenge_end.challenge_hash in db.active_discriminants):
|
||||
writer = db.active_discriminants[challenge_end.challenge_hash]
|
||||
writer.write(b'10')
|
||||
|
@ -135,6 +136,7 @@ async def challenge_end(challenge_end: timelord_protocol.ChallengeEnd):
|
|||
db.done_discriminants.append(challenge_end.challenge_hash)
|
||||
await asyncio.sleep(0.5)
|
||||
|
||||
|
||||
@api_request
|
||||
async def proof_of_space_info(proof_of_space_info: timelord_protocol.ProofOfSpaceInfo):
|
||||
"""
|
||||
|
@ -143,15 +145,15 @@ async def proof_of_space_info(proof_of_space_info: timelord_protocol.ProofOfSpac
|
|||
many iterations to run for. TODO: process should be started in challenge_start instead.
|
||||
"""
|
||||
|
||||
while (True):
|
||||
while True:
|
||||
async with db.lock:
|
||||
if (proof_of_space_info.challenge_hash in db.active_discriminants):
|
||||
writer = db.active_discriminants[proof_of_space_info.challenge_hash]
|
||||
writer.write((str(len(str(proof_of_space_info.iterations_needed)))
|
||||
+ str(proof_of_space_info.iterations_needed)).encode())
|
||||
writer.write((str(len(str(proof_of_space_info.iterations_needed)))
|
||||
+ str(proof_of_space_info.iterations_needed)).encode())
|
||||
await writer.drain()
|
||||
return
|
||||
return
|
||||
if (proof_of_space_info.challenge_hash in db.done_discriminants):
|
||||
log.info("Got iters for a finished challenge")
|
||||
return
|
||||
return
|
||||
await asyncio.sleep(0.5)
|
||||
|
|
|
@ -208,5 +208,5 @@ class BlockTools:
|
|||
|
||||
|
||||
# print(create_genesis_block().serialize())
|
||||
# bt = BlockTools()
|
||||
# print(bt.create_genesis_block(bytes([4]*32)).serialize())
|
||||
bt = BlockTools()
|
||||
print(bt.create_genesis_block(bytes([4]*32)).serialize())
|
||||
|
|
Loading…
Reference in New Issue