Skip to content
This repository has been archived by the owner on Jul 18, 2024. It is now read-only.

Pass HTTP-related metadata (headers, cookies, etc.) to PoolStore.add_farmer #4

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Pass HTTP-related metadata (headers, cookies, etc.) to `PoolStore.add…
…_farmer`
  • Loading branch information
mpnowacki-reef committed Jul 6, 2021

Verified

This commit was signed with the committer’s verified signature.
mariancraciun1983 Marian Craciun
commit 7a4be8dc8e6d9b780c18ef58b8b730d11d549435
6 changes: 3 additions & 3 deletions pool/pool.py
Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@
from .store.abstract import AbstractPoolStore
from .store.sqlite_store import SqlitePoolStore
from .record import FarmerRecord
from .util import error_dict
from .util import error_dict, RequestMetadata


class Pool:
@@ -547,7 +547,7 @@ async def check_and_confirm_partial(self, partial: PostPartialRequest, points_re
error_stack = traceback.format_exc()
self.log.error(f"Exception in confirming partial: {e} {error_stack}")

async def add_farmer(self, request: PostFarmerRequest) -> Dict:
async def add_farmer(self, request: PostFarmerRequest, metadata: RequestMetadata) -> Dict:
async with self.store.lock:
farmer_record: Optional[FarmerRecord] = await self.store.get_farmer_record(request.payload.launcher_id)
if farmer_record is not None:
@@ -613,7 +613,7 @@ async def add_farmer(self, request: PostFarmerRequest) -> Dict:
True,
)
self.scan_p2_singleton_puzzle_hashes.add(p2_singleton_puzzle_hash)
await self.store.add_farmer_record(farmer_record)
await self.store.add_farmer_record(farmer_record, metadata)

return PostFarmerResponse(self.welcome_message).to_json_dict()

15 changes: 13 additions & 2 deletions pool/pool_server.py
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@
from .record import FarmerRecord
from .pool import Pool
from .store.abstract import AbstractPoolStore
from .util import error_response
from .util import error_response, RequestMetadata


def allow_cors(response: web.Response) -> web.Response:
@@ -134,6 +134,16 @@ async def get_farmer(self, request_obj) -> web.Response:
self.pool.log.info(f"get_farmer response {response.to_json_dict()}, " f"launcher_id: {launcher_id.hex()}")
return obj_to_response(response)

def post_metadata_from_request(self, request_obj):
return RequestMetadata(
url=request_obj.url,
scheme=request_obj.scheme,
headers=request_obj.headers,
cookies=dict(request_obj.cookies),
query=dict(request_obj.query),
remote=request_obj.remote,
)

async def post_farmer(self, request_obj) -> web.Response:
# TODO(pool): add rate limiting
post_farmer_request: PostFarmerRequest = PostFarmerRequest.from_json_dict(await request_obj.json())
@@ -146,7 +156,8 @@ async def post_farmer(self, request_obj) -> web.Response:
if authentication_token_error is not None:
return authentication_token_error

post_farmer_response = await self.pool.add_farmer(post_farmer_request)
post_farmer_response = await self.pool.add_farmer(
post_farmer_request, self.post_metadata_from_request(request_obj))

self.pool.log.info(
f"post_farmer response {post_farmer_response}, "
2 changes: 1 addition & 1 deletion pool/record.py
Original file line number Diff line number Diff line change
@@ -21,4 +21,4 @@ class FarmerRecord(Streamable):
points: uint64 # Total points accumulated since last rest (or payout)
difficulty: uint64 # Current difficulty for this farmer
payout_instructions: str # This is where the pool will pay out rewards to the farmer
is_pool_member: bool # If the farmer leaves the pool, this gets set to False
is_pool_member: bool # If the farmer leaves the pool, this gets set to False
3 changes: 2 additions & 1 deletion pool/store/abstract.py
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
from chia.util.ints import uint64

from ..record import FarmerRecord
from ..util import RequestMetadata


class AbstractPoolStore(ABC):
@@ -22,7 +23,7 @@ async def connect(self):
"""Perform IO-related initialization"""

@abstractmethod
async def add_farmer_record(self, farmer_record: FarmerRecord):
async def add_farmer_record(self, farmer_record: FarmerRecord, metadata: RequestMetadata):
"""Persist a new Farmer in the store"""

@abstractmethod
3 changes: 2 additions & 1 deletion pool/store/sqlite_store.py
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@

from .abstract import AbstractPoolStore
from ..record import FarmerRecord
from ..util import RequestMetadata


class SqlitePoolStore(AbstractPoolStore):
@@ -68,7 +69,7 @@ def _row_to_farmer_record(row) -> FarmerRecord:
True if row[10] == 1 else False,
)

async def add_farmer_record(self, farmer_record: FarmerRecord):
async def add_farmer_record(self, farmer_record: FarmerRecord, metadata: RequestMetadata):
cursor = await self.connection.execute(
f"INSERT OR REPLACE INTO farmer VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
(
20 changes: 20 additions & 0 deletions pool/util.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from dataclasses import dataclass
from typing import Dict, Mapping

from chia.protocols.pool_protocol import PoolErrorCode, ErrorResponse
from chia.util.ints import uint16
from chia.util.json_util import obj_to_response
@@ -11,3 +14,20 @@ def error_response(code: PoolErrorCode, message: str):
def error_dict(code: PoolErrorCode, message: str):
error: ErrorResponse = ErrorResponse(uint16(code.value), message)
return error.to_json_dict()


@dataclass
class RequestMetadata:
"""
HTTP-related metadata passed with HTTP requests
"""
url: str # original request url, as used by the client
scheme: str # for example https
headers: Mapping[str, str] # header names are all lower case
cookies: Dict[str, str]
query: Dict[str, str] # query params passed in the url. These are not used by chia clients at the moment, but
# allow for a lot of adjustments and thanks to including them now they can be used without introducing breaking changes
remote: str # address of the client making the request

def __post_init__(self):
self.headers = {k.lower(): v for k, v in self.headers.items()}