Fix ui and RPC

This commit is contained in:
Mariano Sorgente 2020-02-07 23:25:26 -05:00
parent ca14e9ed18
commit bef0209e52
No known key found for this signature in database
GPG Key ID: 0F866338C369278C
6 changed files with 80 additions and 78 deletions

View File

@ -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", {})

View File

@ -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),
]
)

View File

@ -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)

View File

@ -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

View File

@ -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,
]

View File

@ -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