Fix ui and RPC
This commit is contained in:
parent
ca14e9ed18
commit
bef0209e52
|
@ -7,6 +7,7 @@ from src.types.full_block import FullBlock
|
|||
from src.types.header import Header
|
||||
from src.types.sized_bytes import bytes32
|
||||
from src.util.ints import uint16
|
||||
from src.types.hashable.CoinRecord import CoinRecord
|
||||
|
||||
|
||||
class RpcClient:
|
||||
|
@ -76,12 +77,17 @@ class RpcClient:
|
|||
async def stop_node(self) -> Dict:
|
||||
return await self.fetch("stop_node", {})
|
||||
|
||||
async def get_pool_balances(self) -> Dict:
|
||||
response = await self.fetch("get_pool_balances", {})
|
||||
new_response = {}
|
||||
for pk, bal in response.items():
|
||||
new_response[hexstr_to_bytes(pk)] = bal
|
||||
return new_response
|
||||
async def get_unspent_coins(
|
||||
self, puzzle_hash: bytes32, header_hash: Optional[bytes32] = None
|
||||
) -> List:
|
||||
if header_hash is not None:
|
||||
d = {"puzzle_hash": puzzle_hash.hex(), "header_hash": header_hash.hex()}
|
||||
else:
|
||||
d = {"puzzle_hash": puzzle_hash.hex()}
|
||||
return [
|
||||
CoinRecord.from_json(coin)
|
||||
for coin in await self.fetch("get_unspent_coins", d)
|
||||
]
|
||||
|
||||
async def get_heaviest_block_seen(self) -> Header:
|
||||
response = await self.fetch("get_heaviest_block_seen", {})
|
||||
|
|
|
@ -10,6 +10,7 @@ from src.types.header import Header
|
|||
from src.types.full_block import FullBlock
|
||||
from src.types.peer_info import PeerInfo
|
||||
from src.util.ints import uint16, uint64
|
||||
from src.types.sized_bytes import bytes32
|
||||
from src.util.byte_types import hexstr_to_bytes
|
||||
|
||||
|
||||
|
@ -166,25 +167,23 @@ class RpcApiHandler:
|
|||
self.stop_cb()
|
||||
return obj_to_response("")
|
||||
|
||||
# async def get_pool_balances(self, request) -> web.Response:
|
||||
# """
|
||||
# Retrieves the coinbase balances earned by all pools.
|
||||
# TODO: remove after transactions and coins are added.
|
||||
# """
|
||||
async def get_unspent_coins(self, request) -> web.Response:
|
||||
"""
|
||||
Retrieves the unspent coins for a given puzzlehash.
|
||||
"""
|
||||
request_data = await request.json()
|
||||
puzzle_hash = hexstr_to_bytes(request_data["puzzle_hash"])
|
||||
if "header_hash" in request_data:
|
||||
header_hash = bytes32(hexstr_to_bytes(request_data["header_hash"]))
|
||||
header = self.full_node.blockchain.headers.get(header_hash)
|
||||
else:
|
||||
header = None
|
||||
|
||||
# ppks: List[
|
||||
# Tuple[uint32, PublicKey]
|
||||
# ] = await self.full_node.store.get_pool_pks_hack()
|
||||
coin_records = await self.full_node.blockchain.unspent_store.get_coin_records_by_puzzle_hash(
|
||||
puzzle_hash, header
|
||||
)
|
||||
|
||||
# coin_balances: Dict[str, uint64] = {}
|
||||
# for height, pk in ppks:
|
||||
# pool_pk = f"0x{bytes(pk).hex()}"
|
||||
# if pool_pk not in coin_balances:
|
||||
# coin_balances[pool_pk] = uint64(0)
|
||||
# coin_balances[pool_pk] = uint64(
|
||||
# coin_balances[pool_pk] + calculate_block_reward(height)
|
||||
# )
|
||||
# return obj_to_response(coin_balances)
|
||||
return obj_to_response(coin_records)
|
||||
|
||||
async def get_heaviest_block_seen(self, request) -> web.Response:
|
||||
"""
|
||||
|
@ -218,7 +217,7 @@ async def start_rpc_server(full_node: FullNode, stop_node_cb: Callable, rpc_port
|
|||
web.post("/open_connection", handler.open_connection),
|
||||
web.post("/close_connection", handler.close_connection),
|
||||
web.post("/stop_node", handler.stop_node),
|
||||
# web.post("/get_pool_balances", handler.get_pool_balances),
|
||||
web.post("/get_unspent_coins", handler.get_unspent_coins),
|
||||
web.post("/get_heaviest_block_seen", handler.get_heaviest_block_seen),
|
||||
]
|
||||
)
|
||||
|
|
|
@ -4,7 +4,6 @@ from typing import Callable, List, Optional, Tuple, Dict
|
|||
import aiohttp
|
||||
|
||||
import asyncssh
|
||||
from blspy import PrivateKey, PublicKey
|
||||
from yaml import safe_load
|
||||
|
||||
from definitions import ROOT_DIR
|
||||
|
@ -23,6 +22,7 @@ from src.types.header import Header
|
|||
from src.types.sized_bytes import bytes32
|
||||
from src.util.ints import uint64
|
||||
from src.rpc.rpc_client import RpcClient
|
||||
from src.util.byte_types import hexstr_to_bytes
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -103,8 +103,6 @@ class FullNodeUI:
|
|||
self.block = None
|
||||
self.closed: bool = False
|
||||
self.num_blocks: int = 10
|
||||
self.num_top_block_pools: int = 10
|
||||
self.top_winners: List[Tuple[uint64, bytes32]] = []
|
||||
self.our_winners: List[Tuple[uint64, bytes32]] = []
|
||||
self.prev_route: str = "home/"
|
||||
self.route: str = "home/"
|
||||
|
@ -112,14 +110,14 @@ class FullNodeUI:
|
|||
self.parent_close_cb = parent_close_cb
|
||||
self.kb = self.setup_keybindings()
|
||||
self.style = Style([("error", "#ff0044")])
|
||||
self.pool_pks: List[PublicKey] = []
|
||||
self.puzzle_hashes: List[bytes32] = []
|
||||
key_config_filename = ROOT_DIR / "config" / "keys.yaml"
|
||||
if key_config_filename.exists():
|
||||
config = safe_load(open(key_config_filename, "r"))
|
||||
|
||||
self.pool_pks = [
|
||||
PrivateKey.from_bytes(bytes.fromhex(ce)).get_public_key()
|
||||
for ce in config["pool_sks"]
|
||||
self.puzzle_hashes = [
|
||||
hexstr_to_bytes(config["pool_target"]),
|
||||
hexstr_to_bytes(config["farmer_target"]),
|
||||
]
|
||||
|
||||
self.draw_initial()
|
||||
|
@ -211,13 +209,9 @@ class FullNodeUI:
|
|||
)
|
||||
self.search_block_field.accept_handler = self.async_to_sync(self.search_block)
|
||||
|
||||
self.top_block_pools_msg = Label(text=f"Top block pools")
|
||||
self.top_block_pools_labels = [
|
||||
Label(text="Top block pool") for _ in range(self.num_top_block_pools)
|
||||
]
|
||||
self.our_pools_msg = Label(text=f"Our pool winnings")
|
||||
self.our_pools_msg = Label(text=f"Our winnings")
|
||||
self.our_pools_labels = [
|
||||
Label(text="Our winnings") for _ in range(len(self.pool_pks))
|
||||
Label(text="Our winnings") for _ in range(len(self.puzzle_hashes))
|
||||
]
|
||||
|
||||
self.close_ui_button = Button("Close UI", handler=self.close)
|
||||
|
@ -339,7 +333,7 @@ class FullNodeUI:
|
|||
else:
|
||||
self.syncing.text = "Not syncing"
|
||||
|
||||
total_iters = self.lca_block.challenge.total_iters
|
||||
total_iters = self.lca_block.data.total_iters
|
||||
|
||||
new_block_labels = []
|
||||
for i, b in enumerate(self.latest_blocks):
|
||||
|
@ -353,16 +347,6 @@ class FullNodeUI:
|
|||
)
|
||||
new_block_labels.append(self.latest_blocks_labels[i])
|
||||
|
||||
top_block_pools_labels = self.top_block_pools_labels
|
||||
if len(self.top_winners) > 0:
|
||||
new_top_block_pools_labels = []
|
||||
for i, (winnings, pk) in enumerate(self.top_winners):
|
||||
self.top_block_pools_labels[
|
||||
i
|
||||
].text = f"Public key {pk.hex()}: {winnings/1000000000000} chias."
|
||||
new_top_block_pools_labels.append(self.top_block_pools_labels[i])
|
||||
top_block_pools_labels = new_top_block_pools_labels
|
||||
|
||||
our_pools_labels = self.our_pools_labels
|
||||
if len(self.our_winners) > 0:
|
||||
new_our_pools_labels = []
|
||||
|
@ -412,9 +396,6 @@ class FullNodeUI:
|
|||
self.search_block_msg,
|
||||
self.search_block_field,
|
||||
Window(height=1, char="-", style="class:line"),
|
||||
self.top_block_pools_msg,
|
||||
*top_block_pools_labels,
|
||||
Window(height=1, char="-", style="class:line"),
|
||||
self.our_pools_msg,
|
||||
*our_pools_labels,
|
||||
Window(height=1, char="-", style="class:line"),
|
||||
|
@ -486,22 +467,16 @@ class FullNodeUI:
|
|||
self.latest_blocks = await self.get_latest_blocks(self.tips)
|
||||
|
||||
self.data_initialized = True
|
||||
if counter % 50 == 0:
|
||||
# Only request balances periodically, since it's an expensive operation
|
||||
coin_balances: Dict[
|
||||
bytes, uint64
|
||||
] = await self.rpc_client.get_pool_balances()
|
||||
self.top_winners = sorted(
|
||||
[(rewards, key) for key, rewards in coin_balances.items()],
|
||||
reverse=True,
|
||||
)[: self.num_top_block_pools]
|
||||
|
||||
self.our_winners = [
|
||||
(coin_balances[bytes(pk)], bytes(pk))
|
||||
if bytes(pk) in coin_balances
|
||||
else (0, bytes(pk))
|
||||
for pk in self.pool_pks
|
||||
]
|
||||
if counter % 10 == 0:
|
||||
all_coins = []
|
||||
for puzzle_hash in self.puzzle_hashes:
|
||||
coins = await self.rpc_client.get_unspent_coins(
|
||||
puzzle_hash, self.latest_blocks[-1].header_hash
|
||||
)
|
||||
all_coins.append(
|
||||
(sum(coin.coin.amount for coin in coins), puzzle_hash)
|
||||
)
|
||||
self.our_winners = all_coins
|
||||
|
||||
counter += 1
|
||||
await asyncio.sleep(5)
|
||||
|
|
|
@ -210,7 +210,7 @@ class UnspentStore:
|
|||
row = await cursor.fetchone()
|
||||
await cursor.close()
|
||||
if row is not None:
|
||||
return CoinRecord.from_bytes(row[6])
|
||||
return CoinRecord(Coin.from_bytes(row[6]), row[1], row[2], row[3], row[4])
|
||||
return None
|
||||
|
||||
# Checks DB and DiffStores for CoinRecords with puzzle_hash and returns them
|
||||
|
@ -229,7 +229,9 @@ class UnspentStore:
|
|||
rows = await cursor.fetchall()
|
||||
await cursor.close()
|
||||
for row in rows:
|
||||
coins.add(CoinRecord.from_bytes(row[6]).coin)
|
||||
coins.add(
|
||||
CoinRecord(Coin.from_bytes(row[6]), row[1], row[2], row[3], row[4])
|
||||
)
|
||||
return list(coins)
|
||||
|
||||
# TODO figure out if we want to really delete when doing rollback
|
||||
|
|
|
@ -8,6 +8,7 @@ import json
|
|||
from hashlib import sha256
|
||||
from typing import Any, BinaryIO, List, Type, get_type_hints, Union
|
||||
from src.util.byte_types import hexstr_to_bytes
|
||||
from src.types.hashable.Program import Program
|
||||
|
||||
from blspy import (
|
||||
ChainCode,
|
||||
|
@ -50,6 +51,7 @@ unhashable_types = [
|
|||
ExtendedPublicKey,
|
||||
ExtendedPrivateKey,
|
||||
ChainCode,
|
||||
Program,
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ class TestRpc:
|
|||
|
||||
b: Blockchain = await Blockchain.create(unspent_store, store, test_constants)
|
||||
await store.add_block(blocks[0])
|
||||
for i in range(1, 9):
|
||||
for i in range(1, len(blocks)):
|
||||
assert (await b.receive_block(blocks[i]))[
|
||||
0
|
||||
] == ReceiveBlockResult.ADDED_TO_HEAD
|
||||
|
@ -74,6 +74,13 @@ class TestRpc:
|
|||
full_node_1._shutdown()
|
||||
server_1.close_all()
|
||||
|
||||
unspent_store2 = await UnspentStore.create("blockchain_test_2.db")
|
||||
full_node_2 = FullNode(store, b, config, mempool, unspent_store2)
|
||||
server_2 = ChiaServer(test_node_2_port, full_node_2, NodeType.FULL_NODE)
|
||||
full_node_2._set_server(server_2)
|
||||
|
||||
_ = await server_2.start_server("127.0.0.1", None)
|
||||
|
||||
rpc_cleanup = await start_rpc_server(full_node_1, stop_node_cb, test_rpc_port)
|
||||
|
||||
try:
|
||||
|
@ -86,22 +93,33 @@ class TestRpc:
|
|||
assert state["ips"] > 0
|
||||
|
||||
block = await client.get_block(state["lca"].header_hash)
|
||||
assert block == blocks[6]
|
||||
print([b.header_hash for b in blocks])
|
||||
print(block.header_hash)
|
||||
assert block == blocks[8]
|
||||
assert (await client.get_block(bytes([1] * 32))) is None
|
||||
|
||||
header = await client.get_header(state["lca"].header_hash)
|
||||
assert header == blocks[6].header
|
||||
assert header == blocks[8].header
|
||||
|
||||
# TODO implement get pool balances
|
||||
# assert len(await client.get_pool_balances()) > 0
|
||||
coins = await client.get_unspent_coins(
|
||||
blocks[-1].body.coinbase.puzzle_hash, blocks[-1].header_hash
|
||||
)
|
||||
assert len(coins) == 22
|
||||
coins_lca = await client.get_unspent_coins(
|
||||
blocks[-1].body.coinbase.puzzle_hash
|
||||
)
|
||||
assert len(coins_lca) == 18
|
||||
|
||||
assert len(await client.get_connections()) == 0
|
||||
|
||||
unspent_store2 = await UnspentStore.create("blockchain_test_2.db")
|
||||
full_node_2 = FullNode(store, b, config, mempool, unspent_store2)
|
||||
server_2 = ChiaServer(test_node_2_port, full_node_2, NodeType.FULL_NODE)
|
||||
full_node_2._set_server(server_2)
|
||||
await client.open_connection(server_2._host, server_2._port)
|
||||
connections = await client.get_connections()
|
||||
assert len(connections) == 1
|
||||
|
||||
await client.close_connection(connections[0]["node_id"])
|
||||
assert len(await client.get_connections()) == 0
|
||||
|
||||
_ = await server_2.start_server("127.0.0.1", None)
|
||||
await asyncio.sleep(2) # Allow server to start
|
||||
except AssertionError:
|
||||
# Checks that the RPC manages to stop the node
|
||||
|
|
Loading…
Reference in New Issue