Commit 91480b21 authored by confusion's avatar confusion

修改node

parent 201d1562
......@@ -27,9 +27,9 @@ async def subscribe(
fund_collect: AgnosticCollection = Depends(dependencies.get_fund_collect),
beacon_service: BeaconChaService = Depends(BeaconChaService)
):
node_detail = await beacon_service.get_validator(indexOrPubkey=create_node.pub_key)
assert node_detail, "节点不存在,绑定失败"
db_data = BaseNode(**create_node.dict(), index=node_detail.validatorindex)
node_detail_list = await beacon_service.get_validator(index_or_pubkey=create_node.pub_key)
assert node_detail_list, "节点不存在,绑定失败"
db_data = BaseNode(**create_node.dict(), index=node_detail_list[0].validator_index)
# 限制staking基金才可绑定节点
query = {'id': create_node.fund_id, 'user_id': user.id, 'fund_type': FundType.staking}
res = await fund_collect.update_one(
......@@ -75,8 +75,9 @@ async def get_node_info(
"nodes": {"$elemMatch": {"pub_key": pub_key}}
})
assert fund, NotFundError()
validator_detail = await beacon_service.get_validator(pub_key)
response = Response[Validator](data=validator_detail)
validator_detail_list = await beacon_service.get_validator(pub_key)
assert validator_detail_list, NotFundError()
response = Response[Validator](data=validator_detail_list[0])
return response
......@@ -97,8 +98,8 @@ async def get_node_deposit(
"nodes": {"$elemMatch": {"pub_key": pub_key}}
})
assert fund, NotFundError()
validator_deposit = await beacon_service.get_validator_deposit(pub_key)
response = Response[List[ValidatorDeposit]](data=validator_deposit)
validator_deposit_list = await beacon_service.get_validator_deposit(pub_key)
response = Response[List[ValidatorDeposit]](data=validator_deposit_list)
return response
......@@ -106,7 +107,7 @@ async def get_node_deposit(
"/validator/blocks/{index}/",
response_model=PageResponse[ValidatorBlock],
summary="查询节点blocks", description="")
async def node_get_validator_deposit(
async def get_node_blocks(
fund_id: str,
pub_key: str,
user: User = Depends(dependencies.get_current_user),
......@@ -127,19 +128,14 @@ async def node_get_validator_deposit(
start=start,
length=page.page_size
)
response = PageResponse[ValidatorBlock](
data=validator_blocks.data,
**page.dict(),
total=validator_blocks.total
)
return response
return PageResponse[ValidatorBlock](data=validator_blocks.data, **page.dict(), total=validator_blocks.total)
@router.get(
"/validator/income/{pub_key}/",
response_model=Response[ValidatorIncome],
summary="查询节点收益", description="")
async def node_get_validator_deposit(
async def get_node_income(
fund_id: str,
pub_key: str,
user: User = Depends(dependencies.get_current_user),
......@@ -152,7 +148,7 @@ async def node_get_validator_deposit(
"nodes": {"$elemMatch": {"pub_key": pub_key}}
})
assert fund, NotFundError()
validator_income = await beacon_service.get_validator_income(indexOrPubkey=pub_key)
assert validator_income, "没有查到收益"
response = Response[ValidatorIncome](data=validator_income[0])
validator_income_list = await beacon_service.get_validator_income(index_or_pubkey=pub_key)
assert validator_income_list, NotFundError()
response = Response[ValidatorIncome](data=validator_income_list[0])
return response
......@@ -3,18 +3,18 @@ from pydantic import BaseModel, Field
class Validator(BaseModel):
"""质押基本信息"""
activationeligibilityepoch: int = Field(None, title="激活合格编号")
activationepoch: int = Field(None, title="激活编号")
validatorindex: int = Field(None, title="节点编号")
activation_eligibility_epoch: int = Field(None, title="激活合格编号")
activation_epoch: int = Field(None, title="激活编号")
validator_index: int = Field(None, title="节点编号")
pubkey: str = Field(None, title="pubkey")
balance: int = Field(None, title="余额")
effectivebalance: int = Field(None, title="实际余额")
exitepoch: int = Field(None, title="")
lastattestationslot: int = Field(None, title="")
effective_balance: int = Field(None, title="实际余额")
exit_epoch: int = Field(None, title="")
last_attestation_slot: int = Field(None, title="")
slashed: bool = Field(None, title="")
status: str = Field(None, title="")
withdrawableepoch: int = Field(None, title="")
withdrawalcredentials: str = Field(None, title="")
withdraw_able_epoch: int = Field(None, title="")
withdrawal_credentials: str = Field(None, title="")
class ValidatorDeposit(BaseModel):
......@@ -54,4 +54,4 @@ class ValidatorIncome(BaseModel):
performance31d: float = Field(None, title="31日收益")
performance365d: float = Field(None, title="年收益")
rank7d: int = Field(None, title="7日排名")
validatorindex: int = Field(None, title="节点编号")
\ No newline at end of file
validator_index: int = Field(None, title="节点编号")
\ No newline at end of file
......@@ -53,104 +53,76 @@ class BeaconChaService:
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',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Accept': 'application/json'
}
async def get_validator(self, indexOrPubkey: Union[int, str]) -> Validator:
"""获取质押信息"""
url = f"{self.base_url}/api/v1/validator/{indexOrPubkey}"
response = await aio_request(
url=url,
method="GET",
headers=self.headers
)
async def service_request(self, url):
response = await aio_request(url=url, method="GET", headers=self.headers)
assert response["status"] == "OK", RequestHttpException()
response_data = response["data"]
result = Validator(**response_data[0]) if response_data else None
return result
return response
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"
response = await aio_request(
url=url,
method="GET",
headers=self.headers
)
assert response["status"] == "OK", RequestHttpException()
response_data = response["data"]
result = [ValidatorDeposit(**item) for item in response_data]
return result
url = f"{self.base_url}/api/v1/validator/{index_or_pubkey}"
response = await self.service_request(url)
return [Validator(
activation_eligibility_epoch=item["activationeligibilityepoch"],
activation_epoch=item["activationepoch"],
validator_index=item["validatorindex"],
pubkey=item["pubkey"],
balance=item["balance"] / self.eth_decimal,
effective_balance=item["effectivebalance"] / self.eth_decimal,
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"
response = await aio_request(
url=url,
method="GET",
headers=self.headers
)
assert response["status"] == "OK", RequestHttpException()
response_data = response["data"]
result = [ValidatorIncome(
url = f"{self.base_url}/api/v1/validator/{index_or_pubkey}/performance"
data = await self.service_request(url)
return [ValidatorIncome(
balance=item["balance"] / self.eth_decimal,
performance1d=item["performance1d"]/ self.eth_decimal,
performance1d=item["performance1d"] / self.eth_decimal,
performance7d=item["performance7d"] / self.eth_decimal,
performance31d=item["performance31d"] / self.eth_decimal,
performance365d=item["performance365d"] / self.eth_decimal,
rank7d=item["rank7d"],
validatorindex=item["validatorindex"]
) for item in response_data]
return result
) for item in data]
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&_={t}"
response = await aio_request(
url=url,
method="GET",
headers=self.headers
)
data = response["data"]
blocks = []
for item in data:
epoch = re.findall(r'/epoch/(\d+)">', item[0])[0]
slot = re.findall(r'/slot/(\d+)">', item[1])[0]
status = re.findall(r'>(\w+)</', item[2])[0]
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
))
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}"
response = await self.service_request(url)
blocks = [ValidatorBlock(
epoch=re.findall(r'/epoch/(\d+)">', item[0])[0],
slot=re.findall(r'/slot/(\d+)">', item[1])[0],
status=re.findall(r'>(\w+)</', item[2])[0],
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]
) for item in response["data"]]
result = ValidatorBlocks(total=response["recordsTotal"], data=blocks)
return result
async def get_daily_stats(self, index: int):
url = f"{self.base_url}/api/v1/validator/stats/{index}"
response = await aio_request(
url=url,
method="GET",
headers=self.headers
)
response = await self.service_request(url)
return response
async def get_eth_deposits(self, indexOrPubkey: Union[int, str]):
url = f"{self.base_url}/api/v1/validator/{indexOrPubkey}/deposits"
response = await aio_request(
url=url,
method="GET",
headers=self.headers
)
async def get_eth_deposits(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 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