mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2026-08-24 10:05:29 -05:00
* Use a separate config for pooling information * New PlotNFT drivers * PlotNFT2 Wallet * PlotNFT V2 RPCs and CLI * Integrate v2 pooling protocol into farmer * Comment by @cursor * Fix test * Comments by @cursor * whoops * Comments by @cursor * Comments by @cursor * Comments by @cursor * Some tidying * fix test for memo adjustment * tweak additional memos again * empirical testing with v1 pools * Add expiration to `GetAuthRequest` * Remove pyjwt dep * Revert `get_login_link` to old behavior * Add an extra derivation to auth key for v2 * unhardened * Fix login link test * Fix login link test again * Fix network protocol data * Comments by cursor * Fix test * Use correct pool url after redirect * Fix test for coverage * Upstream wallet fixes * Add `REMARK` option to `launch` * pre-commit * chmod * test coverage * Add wallet name * test coverage * moar test coverage * commentsby @cursor * moar test coverage * fix custody architecture namespace * Comments by @matt-o-how * Fix /GET farmer to omit the signature rather than None * Fix protocol test * fix test * comments by @cursor * diff minimizatino * event dispatch * Fix test deadlock * Comments by @cursor * test coverage * Comments by @cursor * Comments by @cursor
209 lines
4.6 KiB
Python
209 lines
4.6 KiB
Python
from __future__ import annotations
|
|
|
|
import time
|
|
from dataclasses import dataclass
|
|
from enum import Enum
|
|
|
|
from chia_rs import G1Element, G2Element, Program, ProofOfSpace
|
|
from chia_rs.sized_bytes import bytes32
|
|
from chia_rs.sized_ints import uint8, uint16, uint32, uint64
|
|
|
|
from chia.util.streamable import Streamable, streamable
|
|
|
|
POOL_PROTOCOL_VERSION = uint8(1)
|
|
|
|
|
|
class PoolErrorCode(Enum):
|
|
REVERTED_SIGNAGE_POINT = 1
|
|
TOO_LATE = 2
|
|
NOT_FOUND = 3
|
|
INVALID_PROOF = 4
|
|
PROOF_NOT_GOOD_ENOUGH = 5
|
|
INVALID_DIFFICULTY = 6
|
|
INVALID_SIGNATURE = 7
|
|
SERVER_EXCEPTION = 8
|
|
INVALID_P2_SINGLETON_PUZZLE_HASH = 9
|
|
FARMER_NOT_KNOWN = 10
|
|
FARMER_ALREADY_KNOWN = 11
|
|
INVALID_AUTHENTICATION_TOKEN = 12
|
|
INVALID_PAYOUT_INSTRUCTIONS = 13
|
|
INVALID_SINGLETON = 14
|
|
DELAY_TIME_TOO_SHORT = 15
|
|
REQUEST_FAILED = 16
|
|
|
|
|
|
# Used to verify GET /farmer and GET /login
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class AuthenticationPayloadV1(Streamable):
|
|
method_name: str
|
|
launcher_id: bytes32
|
|
target_puzzle_hash: bytes32
|
|
authentication_token: uint64
|
|
|
|
|
|
# GET /auth (only v2)
|
|
|
|
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class GetAuthRequest(Streamable):
|
|
launcher_id: bytes32
|
|
timestamp: uint64
|
|
signature: G2Element
|
|
|
|
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class GetAuthResponse(Streamable):
|
|
authentication_token: str
|
|
expiration: uint64
|
|
|
|
|
|
# GET /pool_info
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class GetPoolInfoResponse(Streamable):
|
|
name: str
|
|
logo_url: str
|
|
minimum_difficulty: uint64
|
|
relative_lock_height: uint32
|
|
protocol_version: uint8
|
|
fee: str
|
|
description: str
|
|
target_puzzle_hash: bytes32
|
|
authentication_token_timeout: uint8
|
|
pool_memoization: Program = Program.to(None) # addition from v1
|
|
|
|
|
|
# POST /partial
|
|
|
|
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class PostPartialPayload(Streamable):
|
|
launcher_id: bytes32
|
|
authentication_token: uint64
|
|
proof_of_space: ProofOfSpace
|
|
sp_hash: bytes32
|
|
end_of_sub_slot: bool
|
|
harvester_id: bytes32
|
|
|
|
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class PostPartialRequest(Streamable):
|
|
payload: PostPartialPayload
|
|
authentication_token_v2: str
|
|
aggregate_signature: G2Element
|
|
|
|
|
|
# Response in success case
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class PostPartialResponse(Streamable):
|
|
new_difficulty: uint64
|
|
|
|
|
|
# GET /farmer
|
|
@streamable
|
|
@dataclass(frozen=True, kw_only=True)
|
|
class GetFarmerRequestV2(Streamable):
|
|
authentication_token: uint64
|
|
launcher_id: bytes32
|
|
authentication_token_v2: str
|
|
|
|
|
|
@streamable
|
|
@dataclass(frozen=True, kw_only=True)
|
|
class GetFarmerRequestV1(GetFarmerRequestV2):
|
|
signature: G2Element | None = None
|
|
|
|
|
|
# Response in success case
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class GetFarmerResponse(Streamable):
|
|
authentication_public_key: G1Element
|
|
payout_instructions: str
|
|
current_difficulty: uint64
|
|
current_points: uint64
|
|
|
|
|
|
# POST /farmer
|
|
|
|
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class PostFarmerPayload(Streamable):
|
|
launcher_id: bytes32
|
|
authentication_token: uint64
|
|
authentication_public_key: G1Element
|
|
payout_instructions: str
|
|
suggested_difficulty: uint64 | None
|
|
|
|
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class PostFarmerRequest(Streamable):
|
|
payload: PostFarmerPayload
|
|
signature: G2Element
|
|
|
|
|
|
# Response in success case
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class PostFarmerResponse(Streamable):
|
|
welcome_message: str
|
|
|
|
|
|
# PUT /farmer
|
|
|
|
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class PutFarmerPayload(Streamable):
|
|
launcher_id: bytes32
|
|
authentication_token: uint64
|
|
authentication_public_key: G1Element | None
|
|
payout_instructions: str | None
|
|
suggested_difficulty: uint64 | None
|
|
authentication_token_v2: str
|
|
|
|
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class PutFarmerRequest(Streamable):
|
|
payload: PutFarmerPayload
|
|
signature: G2Element | None
|
|
|
|
|
|
# Response in success case
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class PutFarmerResponse(Streamable):
|
|
authentication_public_key: bool | None
|
|
payout_instructions: bool | None
|
|
suggested_difficulty: bool | None
|
|
|
|
|
|
# Misc
|
|
|
|
|
|
# Response in error case for all endpoints of the pool protocol
|
|
@streamable
|
|
@dataclass(frozen=True)
|
|
class ErrorResponse(Streamable):
|
|
error_code: uint16
|
|
error_message: str | None
|
|
|
|
|
|
# Get the current authentication token according to "Farmer authentication" in SPECIFICATION.md
|
|
def get_current_authentication_token(timeout: uint8) -> uint64:
|
|
return uint64(int(time.time() / 60) / timeout)
|
|
|
|
|
|
# Validate a given authentication token against our local time
|
|
def validate_authentication_token(token: uint64, timeout: uint8) -> bool:
|
|
return abs(token - get_current_authentication_token(timeout)) <= timeout
|