Commit 91480b21 authored by confusion's avatar confusion

修改node

parent 201d1562
...@@ -27,9 +27,9 @@ async def subscribe( ...@@ -27,9 +27,9 @@ async def subscribe(
fund_collect: AgnosticCollection = Depends(dependencies.get_fund_collect), fund_collect: AgnosticCollection = Depends(dependencies.get_fund_collect),
beacon_service: BeaconChaService = Depends(BeaconChaService) beacon_service: BeaconChaService = Depends(BeaconChaService)
): ):
node_detail = await beacon_service.get_validator(indexOrPubkey=create_node.pub_key) node_detail_list = await beacon_service.get_validator(index_or_pubkey=create_node.pub_key)
assert node_detail, "节点不存在,绑定失败" assert node_detail_list, "节点不存在,绑定失败"
db_data = BaseNode(**create_node.dict(), index=node_detail.validatorindex) db_data = BaseNode(**create_node.dict(), index=node_detail_list[0].validator_index)
# 限制staking基金才可绑定节点 # 限制staking基金才可绑定节点
query = {'id': create_node.fund_id, 'user_id': user.id, 'fund_type': FundType.staking} query = {'id': create_node.fund_id, 'user_id': user.id, 'fund_type': FundType.staking}
res = await fund_collect.update_one( res = await fund_collect.update_one(
...@@ -75,8 +75,9 @@ async def get_node_info( ...@@ -75,8 +75,9 @@ async def get_node_info(
"nodes": {"$elemMatch": {"pub_key": pub_key}} "nodes": {"$elemMatch": {"pub_key": pub_key}}
}) })
assert fund, NotFundError() assert fund, NotFundError()
validator_detail = await beacon_service.get_validator(pub_key) validator_detail_list = await beacon_service.get_validator(pub_key)
response = Response[Validator](data=validator_detail) assert validator_detail_list, NotFundError()
response = Response[Validator](data=validator_detail_list[0])
return response return response
...@@ -97,8 +98,8 @@ async def get_node_deposit( ...@@ -97,8 +98,8 @@ async def get_node_deposit(
"nodes": {"$elemMatch": {"pub_key": pub_key}} "nodes": {"$elemMatch": {"pub_key": pub_key}}
}) })
assert fund, NotFundError() assert fund, NotFundError()
validator_deposit = await beacon_service.get_validator_deposit(pub_key) validator_deposit_list = await beacon_service.get_validator_deposit(pub_key)
response = Response[List[ValidatorDeposit]](data=validator_deposit) response = Response[List[ValidatorDeposit]](data=validator_deposit_list)
return response return response
...@@ -106,7 +107,7 @@ async def get_node_deposit( ...@@ -106,7 +107,7 @@ async def get_node_deposit(
"/validator/blocks/{index}/", "/validator/blocks/{index}/",
response_model=PageResponse[ValidatorBlock], response_model=PageResponse[ValidatorBlock],
summary="查询节点blocks", description="") summary="查询节点blocks", description="")
async def node_get_validator_deposit( async def get_node_blocks(
fund_id: str, fund_id: str,
pub_key: str, pub_key: str,
user: User = Depends(dependencies.get_current_user), user: User = Depends(dependencies.get_current_user),
...@@ -127,19 +128,14 @@ async def node_get_validator_deposit( ...@@ -127,19 +128,14 @@ async def node_get_validator_deposit(
start=start, start=start,
length=page.page_size length=page.page_size
) )
response = PageResponse[ValidatorBlock]( return PageResponse[ValidatorBlock](data=validator_blocks.data, **page.dict(), total=validator_blocks.total)
data=validator_blocks.data,
**page.dict(),
total=validator_blocks.total
)
return response
@router.get( @router.get(
"/validator/income/{pub_key}/", "/validator/income/{pub_key}/",
response_model=Response[ValidatorIncome], response_model=Response[ValidatorIncome],
summary="查询节点收益", description="") summary="查询节点收益", description="")
async def node_get_validator_deposit( async def get_node_income(
fund_id: str, fund_id: str,
pub_key: str, pub_key: str,
user: User = Depends(dependencies.get_current_user), user: User = Depends(dependencies.get_current_user),
...@@ -152,7 +148,7 @@ async def node_get_validator_deposit( ...@@ -152,7 +148,7 @@ async def node_get_validator_deposit(
"nodes": {"$elemMatch": {"pub_key": pub_key}} "nodes": {"$elemMatch": {"pub_key": pub_key}}
}) })
assert fund, NotFundError() assert fund, NotFundError()
validator_income = await beacon_service.get_validator_income(indexOrPubkey=pub_key) validator_income_list = await beacon_service.get_validator_income(index_or_pubkey=pub_key)
assert validator_income, "没有查到收益" assert validator_income_list, NotFundError()
response = Response[ValidatorIncome](data=validator_income[0]) response = Response[ValidatorIncome](data=validator_income_list[0])
return response return response
...@@ -3,18 +3,18 @@ from pydantic import BaseModel, Field ...@@ -3,18 +3,18 @@ from pydantic import BaseModel, Field
class Validator(BaseModel): class Validator(BaseModel):
"""质押基本信息""" """质押基本信息"""
activationeligibilityepoch: int = Field(None, title="激活合格编号") activation_eligibility_epoch: int = Field(None, title="激活合格编号")
activationepoch: int = Field(None, title="激活编号") activation_epoch: int = Field(None, title="激活编号")
validatorindex: int = Field(None, title="节点编号") validator_index: int = Field(None, title="节点编号")
pubkey: str = Field(None, title="pubkey") pubkey: str = Field(None, title="pubkey")
balance: int = Field(None, title="余额") balance: int = Field(None, title="余额")
effectivebalance: int = Field(None, title="实际余额") effective_balance: int = Field(None, title="实际余额")
exitepoch: int = Field(None, title="") exit_epoch: int = Field(None, title="")
lastattestationslot: int = Field(None, title="") last_attestation_slot: int = Field(None, title="")
slashed: bool = Field(None, title="") slashed: bool = Field(None, title="")
status: str = Field(None, title="") status: str = Field(None, title="")
withdrawableepoch: int = Field(None, title="") withdraw_able_epoch: int = Field(None, title="")
withdrawalcredentials: str = Field(None, title="") withdrawal_credentials: str = Field(None, title="")
class ValidatorDeposit(BaseModel): class ValidatorDeposit(BaseModel):
...@@ -54,4 +54,4 @@ class ValidatorIncome(BaseModel): ...@@ -54,4 +54,4 @@ class ValidatorIncome(BaseModel):
performance31d: float = Field(None, title="31日收益") performance31d: float = Field(None, title="31日收益")
performance365d: float = Field(None, title="年收益") performance365d: float = Field(None, title="年收益")
rank7d: int = Field(None, title="7日排名") rank7d: int = Field(None, title="7日排名")
validatorindex: int = Field(None, title="节点编号") validator_index: int = Field(None, title="节点编号")
\ No newline at end of file \ No newline at end of file
...@@ -53,104 +53,76 @@ class BeaconChaService: ...@@ -53,104 +53,76 @@ class BeaconChaService:
headers = { headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36',
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Accept': 'application/json', 'Accept': 'application/json'
} }
async def get_validator(self, indexOrPubkey: Union[int, str]) -> Validator: async def service_request(self, url):
"""获取质押信息""" response = await aio_request(url=url, method="GET", headers=self.headers)
url = f"{self.base_url}/api/v1/validator/{indexOrPubkey}"
response = await aio_request(
url=url,
method="GET",
headers=self.headers
)
assert response["status"] == "OK", RequestHttpException() assert response["status"] == "OK", RequestHttpException()
response_data = response["data"] return response
result = Validator(**response_data[0]) if response_data else None
return result
async def get_validator_deposit(self, indexOrPubkey: Union[int, str]): async def get_validator(self, index_or_pubkey: Union[int, str]) -> List[Validator]:
"""获取质押信息""" """获取质押信息"""
url = f"{self.base_url}/api/v1/validator/{indexOrPubkey}/deposits" url = f"{self.base_url}/api/v1/validator/{index_or_pubkey}"
response = await aio_request( response = await self.service_request(url)
url=url, return [Validator(
method="GET", activation_eligibility_epoch=item["activationeligibilityepoch"],
headers=self.headers activation_epoch=item["activationepoch"],
) validator_index=item["validatorindex"],
assert response["status"] == "OK", RequestHttpException() pubkey=item["pubkey"],
response_data = response["data"] balance=item["balance"] / self.eth_decimal,
result = [ValidatorDeposit(**item) for item in response_data] effective_balance=item["effectivebalance"] / self.eth_decimal,
return result exit_epoch=item["exitepoch"],
last_attestation_slot=item["lastattestationslot"],
slashed=item["slashed"],
status=item["status"],
withdraw_able_epoch=item["withdrawableepoch"],
withdrawal_credentials=item["withdrawalcredentials"],
) for item in response["data"]]
async def get_validator_deposit(self, index_or_pubkey: Union[int, str]):
"""获取质押信息"""
url = f"{self.base_url}/api/v1/validator/{index_or_pubkey}/deposits"
response = await self.service_request(url)
return [ValidatorDeposit(**item) for item in response["data"]]
async def get_validator_income(self, indexOrPubkey: Union[int, str]) -> List[ValidatorIncome]: async def get_validator_income(self, index_or_pubkey: Union[int, str]) -> List[ValidatorIncome]:
"""获取质押收益""" """获取质押收益"""
url = f"{self.base_url}/api/v1/validator/{indexOrPubkey}/performance" url = f"{self.base_url}/api/v1/validator/{index_or_pubkey}/performance"
response = await aio_request( data = await self.service_request(url)
url=url, return [ValidatorIncome(
method="GET",
headers=self.headers
)
assert response["status"] == "OK", RequestHttpException()
response_data = response["data"]
result = [ValidatorIncome(
balance=item["balance"] / self.eth_decimal, balance=item["balance"] / self.eth_decimal,
performance1d=item["performance1d"]/ self.eth_decimal, performance1d=item["performance1d"] / self.eth_decimal,
performance7d=item["performance7d"] / self.eth_decimal, performance7d=item["performance7d"] / self.eth_decimal,
performance31d=item["performance31d"] / self.eth_decimal, performance31d=item["performance31d"] / self.eth_decimal,
performance365d=item["performance365d"] / self.eth_decimal, performance365d=item["performance365d"] / self.eth_decimal,
rank7d=item["rank7d"], rank7d=item["rank7d"],
validatorindex=item["validatorindex"] validatorindex=item["validatorindex"]
) for item in response_data] ) for item in data]
return result
async def get_validator_blocks(self, index: int, start: int = 0, length: int = 10) -> ValidatorBlocks: async def get_validator_blocks(self, index: int, start: int = 0, length: int = 10) -> ValidatorBlocks:
t = time.time() * 1000 url = f"https://beaconcha.in/validator/{index}/proposedblocks?draw=1&columns%5B0%5D%5Bdata%5D=0&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=1&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=false&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=2&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=3&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=false&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=4&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=false&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=5&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=true&columns%5B5%5D%5Borderable%5D=true&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B6%5D%5Bdata%5D=6&columns%5B6%5D%5Bname%5D=&columns%5B6%5D%5Bsearchable%5D=true&columns%5B6%5D%5Borderable%5D=true&columns%5B6%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B6%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B7%5D%5Bdata%5D=7&columns%5B7%5D%5Bname%5D=&columns%5B7%5D%5Bsearchable%5D=true&columns%5B7%5D%5Borderable%5D=false&columns%5B7%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B7%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B8%5D%5Bdata%5D=8&columns%5B8%5D%5Bname%5D=&columns%5B8%5D%5Bsearchable%5D=true&columns%5B8%5D%5Borderable%5D=true&columns%5B8%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B8%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B9%5D%5Bdata%5D=9&columns%5B9%5D%5Bname%5D=&columns%5B9%5D%5Bsearchable%5D=true&columns%5B9%5D%5Borderable%5D=true&columns%5B9%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B9%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=desc&start={start}&length={length}&search%5Bvalue%5D=&search%5Bregex%5D=false&_={time.time() * 1000}"
url = f"https://beaconcha.in/validator/{index}/proposedblocks?draw=1&columns%5B0%5D%5Bdata%5D=0&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=1&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=false&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=2&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=3&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=false&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=4&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=false&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=5&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=true&columns%5B5%5D%5Borderable%5D=true&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B6%5D%5Bdata%5D=6&columns%5B6%5D%5Bname%5D=&columns%5B6%5D%5Bsearchable%5D=true&columns%5B6%5D%5Borderable%5D=true&columns%5B6%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B6%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B7%5D%5Bdata%5D=7&columns%5B7%5D%5Bname%5D=&columns%5B7%5D%5Bsearchable%5D=true&columns%5B7%5D%5Borderable%5D=false&columns%5B7%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B7%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B8%5D%5Bdata%5D=8&columns%5B8%5D%5Bname%5D=&columns%5B8%5D%5Bsearchable%5D=true&columns%5B8%5D%5Borderable%5D=true&columns%5B8%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B8%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B9%5D%5Bdata%5D=9&columns%5B9%5D%5Bname%5D=&columns%5B9%5D%5Bsearchable%5D=true&columns%5B9%5D%5Borderable%5D=true&columns%5B9%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B9%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=desc&start={start}&length={length}&search%5Bvalue%5D=&search%5Bregex%5D=false&_={t}" response = await self.service_request(url)
response = await aio_request( blocks = [ValidatorBlock(
url=url, epoch=re.findall(r'/epoch/(\d+)">', item[0])[0],
method="GET", slot=re.findall(r'/slot/(\d+)">', item[1])[0],
headers=self.headers status=re.findall(r'>(\w+)</', item[2])[0],
) timestamp=re.findall(r'data-timestamp=\"(\d+)\">', item[3])[0],
data = response["data"] root_hash=re.findall(r'data-clipboard-text=(\w+)>', item[4])[0],
blocks = [] att=item[5],
for item in data: dep=item[6],
epoch = re.findall(r'/epoch/(\d+)">', item[0])[0] proposers=item[7],
slot = re.findall(r'/slot/(\d+)">', item[1])[0] ex=item[8]
status = re.findall(r'>(\w+)</', item[2])[0] ) for item in response["data"]]
timestamp = re.findall(r'data-timestamp=\"(\d+)\">', item[3])[0]
root_hash = re.findall(r'data-clipboard-text=(\w+)>', item[4])[0]
att = item[5]
dep = item[6]
proposers = item[7]
ex = item[8]
blocks.append(ValidatorBlock(
epoch=epoch,
slot=slot,
status=status,
timestamp=timestamp,
root_hash=root_hash,
att=att,
dep=dep,
proposers=proposers,
ex=ex
))
result = ValidatorBlocks(total=response["recordsTotal"], data=blocks) result = ValidatorBlocks(total=response["recordsTotal"], data=blocks)
return result return result
async def get_daily_stats(self, index: int): async def get_daily_stats(self, index: int):
url = f"{self.base_url}/api/v1/validator/stats/{index}" url = f"{self.base_url}/api/v1/validator/stats/{index}"
response = await aio_request( response = await self.service_request(url)
url=url,
method="GET",
headers=self.headers
)
return response return response
async def get_eth_deposits(self, indexOrPubkey: Union[int, str]): async def get_eth_deposits(self, index_or_pubkey: Union[int, str]):
url = f"{self.base_url}/api/v1/validator/{indexOrPubkey}/deposits" url = f"{self.base_url}/api/v1/validator/{index_or_pubkey}/deposits"
response = await aio_request( response = await self.service_request(url)
url=url,
method="GET",
headers=self.headers
)
return response return response
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment