get add rpcs, temp add manager to dl

This commit is contained in:
almog 2021-10-27 14:58:36 +03:00
parent 16be1b86af
commit ada058fcdc
No known key found for this signature in database
GPG Key ID: CB2C7BBD0071DFDC
3 changed files with 130 additions and 37 deletions

View File

@ -10,7 +10,9 @@ from chia.data_layer.data_store import DataStore
from chia.server.server import ChiaServer
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.util.db_wrapper import DBWrapper
from chia.util.ints import uint64
from chia.util.path import mkdir, path_from_root
from chia.wallet.wallet_state_manager import WalletStateManager
class DataLayer:
@ -22,17 +24,16 @@ class DataLayer:
server: Any
log: logging.Logger
wallet: DataLayerWallet
# _shut_down: bool
# root_path: Path
wallet_state_manager: Optional[WalletStateManager]
state_changed_callback: Optional[Callable[..., object]]
initialized: bool
# _ui_tasks: Set[asyncio.Task]
def __init__(
self,
# TODO: Is this at least `Dict[str, Any]`?
config: Dict[Any, Any],
root_path: Path,
wallet_state_manager: Optional[WalletStateManager],
consensus_constants: ConsensusConstants,
name: Optional[str] = None,
):
@ -45,7 +46,7 @@ class DataLayer:
self.wallet = DataLayerWallet()
self.config = config
self.server = None
# self.constants = consensus_constants
self.wallet_state_manager = wallet_state_manager
self.state_changed_callback = None
self.log = logging.getLogger(name if name is None else __name__)
@ -78,13 +79,24 @@ class DataLayer:
async def _await_closed(self) -> None:
await self.connection.close()
async def init_exsiting_data_wallet(self) -> None:
# todo implement
pass
async def create_store(self) -> bytes32:
# todo create singelton with wavaluellet and get id
store_id = await self.wallet.create_data_store()
res = await self.data_store.create_tree(store_id)
if res is False:
self.log.error("Failed to create tree")
return store_id
wallet_state_manager = self.wallet_state_manager
main_wallet = wallet_state_manager.main_wallet
amount = uint64(1) # todo what should amount be ?
root_hash = b"" # todo what is the root value on a newly empty created tree?
async with self.wallet_state_manager.lock:
res = await self.wallet.create_new_dl_wallet(self.wallet_state_manager, main_wallet, amount, root_hash)
if res is False:
self.log.error("Failed to create tree")
self.wallet = res
tree_id = res.dl_info.origin_coin.name()
res = await self.data_store.create_tree(tree_id)
assert res
return tree_id
async def insert(
self,
@ -105,8 +117,10 @@ class DataLayer:
key = change["key"]
await self.data_store.delete(key, tree_id)
# state = await self.data_store.get_table_state(table)
# await self.data_layer_wallet.uptate_table_state(table, state, std_hash(action_list))
root = await self.data_store.get_tree_root(tree_id)
assert root.node_hash
res = await self.wallet.create_update_state_spend(root.node_hash)
assert res
# todo need to mark data as pending and change once tx is confirmed
return True
@ -122,11 +136,8 @@ class DataLayer:
self.log.error("Failed to create tree")
return res
# def _state_changed(self, change: str):
# if self.state_changed_callback is not None:
# self.state_changed_callback(change)
# async def _refresh_ui_connections(self, sleep_before: float = 0):
# if sleep_before > 0:
# await asyncio.sleep(sleep_before)
# self._state_changed("peer_changed_peak")
async def get_ancestors(self, node_hash: bytes32, store_id: bytes32) -> bytes32:
res = await self.data_store.get_ancestors(store_id, node_hash)
if res is None:
self.log.error("Failed to create tree")
return res

View File

@ -46,6 +46,7 @@ class DataLayerRpcApi:
"/create_kv_store": self.create_kv_store,
"/update_kv_store": self.update_kv_store,
"/get_value": self.get_value,
"/get_pairs": self.get_pairs,
}
async def create_kv_store(self, request: Dict[str, Any] = None) -> Dict[str, Any]:
@ -63,13 +64,18 @@ class DataLayerRpcApi:
value = await self.service.get_pairs(store_id)
return {"data": value.hex()}
async def get_ancestors(self, request: Dict[str, Any]) -> Dict[str, Any]:
store_id = bytes32(hexstr_to_bytes(request["id"]))
key = hexstr_to_bytes(request["key"])
value = await self.service.get_ancestors(key, store_id)
return {"data": value.hex()}
async def update_kv_store(self, request: Dict[str, Any]):
"""
rows_to_add a list of clvmobjects as bytes to add to talbe
rows_to_add a list of clvm objects as bytes to add to talbe
rows_to_remove a list of row hashes to remove
"""
changelist = [process_change(change) for change in request["changelist"]]
store_id = bytes32(hexstr_to_bytes(request["id"]))
# todo input checks
await self.service.insert(store_id, changelist)

View File

@ -7,22 +7,50 @@ from chia.consensus.default_constants import DEFAULT_CONSTANTS
from chia.data_layer.data_layer import DataLayer
from chia.data_layer.data_store import DataStore
from chia.rpc.data_layer_rpc_api import DataLayerRpcApi
from chia.simulator.simulator_protocol import FarmNewBlockProtocol
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.types.blockchain_format.program import Program
from chia.types.peer_info import PeerInfo
from chia.util.byte_types import hexstr_to_bytes
from chia.util.config import load_config
from chia.util.db_wrapper import DBWrapper
from chia.util.hash import std_hash
from chia.util.ints import uint16
from chia.wallet.wallet_node import WalletNode
from chia.wallet.wallet_state_manager import WalletStateManager
from tests.core.data_layer.util import ChiaRoot
from tests.setup_nodes import setup_simulators_and_wallets, self_hostname
@pytest.fixture(scope="function")
async def wallet_node():
async for _ in setup_simulators_and_wallets(1, 1, {}):
yield _
@pytest.mark.asyncio
async def test_create_insert_get(chia_root: ChiaRoot) -> None:
async def test_create_insert_get(chia_root: ChiaRoot, wallet_node):
root = chia_root.path
config = load_config(root, "config.yaml")
config["data_layer"]["database_path"] = "data_layer_test.sqlite"
data_layer = DataLayer(config["data_layer"], root_path=root, consensus_constants=DEFAULT_CONSTANTS)
full_nodes, wallets = wallet_node
full_node_api = full_nodes[0]
full_node_server = full_node_api.server
wallet, wallet_server = wallets[0]
# wallet_0 = wallet.wallet_state_manager.main_wallet
# ph = await wallet_0.get_new_puzzlehash()
# await wallet_server.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
#
# for i in range(3):
# await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
data_layer = DataLayer(
config["data_layer"],
root_path=root,
wallet_state_manager=wallet.wallet_state_manager,
consensus_constants=DEFAULT_CONSTANTS,
)
connection = await aiosqlite.connect(data_layer.db_path)
data_layer.connection = connection
data_layer.db_wrapper = DBWrapper(data_layer.connection)
@ -45,11 +73,17 @@ async def test_create_insert_get(chia_root: ChiaRoot) -> None:
@pytest.mark.asyncio
async def test_create_double_insert(chia_root: ChiaRoot) -> None:
async def test_create_double_insert(chia_root: ChiaRoot, wallet_node):
root = chia_root.path
config = load_config(root, "config.yaml")
config["data_layer"]["database_path"] = "data_layer_test.sqlite"
data_layer = DataLayer(config["data_layer"], root_path=root, consensus_constants=DEFAULT_CONSTANTS)
wallet = wallet_node[1][0][0]
data_layer = DataLayer(
config["data_layer"],
root_path=root,
wallet_state_manager=wallet.wallet_state_manager,
consensus_constants=DEFAULT_CONSTANTS,
)
connection = await aiosqlite.connect(data_layer.db_path)
data_layer.connection = connection
data_layer.db_wrapper = DBWrapper(data_layer.connection)
@ -80,11 +114,17 @@ async def test_create_double_insert(chia_root: ChiaRoot) -> None:
@pytest.mark.asyncio
async def test_get_pairs(chia_root: ChiaRoot) -> None:
async def test_get_pairs(chia_root: ChiaRoot, wallet_node):
root = chia_root.path
config = load_config(root, "config.yaml")
config["data_layer"]["database_path"] = "data_layer_test.sqlite"
data_layer = DataLayer(config["data_layer"], root_path=root, consensus_constants=DEFAULT_CONSTANTS)
wallet = wallet_node[1][0][0]
data_layer = DataLayer(
config["data_layer"],
root_path=root,
wallet_state_manager=wallet.wallet_state_manager,
consensus_constants=DEFAULT_CONSTANTS,
)
connection = await aiosqlite.connect(data_layer.db_path)
data_layer.connection = connection
data_layer.db_wrapper = DBWrapper(data_layer.connection)
@ -109,11 +149,47 @@ async def test_get_pairs(chia_root: ChiaRoot) -> None:
res = await rpc_api.create_kv_store()
tree_id = bytes32(hexstr_to_bytes(res["id"]))
await rpc_api.update_kv_store({"id": tree_id.hex(), "changelist": changelist})
val = await rpc_api.get_value({"id": tree_id.hex(), "key": key1.hex()})
assert hexstr_to_bytes(val["data"]) == value1
val = await rpc_api.get_value({"id": tree_id.hex(), "key": key1.hex()})
changelist = [{"action": "delete", "key": key1.hex()}]
await rpc_api.update_kv_store({"id": tree_id.hex(), "changelist": changelist})
with pytest.raises(Exception):
val = await rpc_api.get_value({"id": tree_id.hex(), "key": key1.hex()})
val = await rpc_api.get_pairs({"id": tree_id.hex()})
# todo check values match
await connection.close()
@pytest.mark.asyncio
async def test_get_ancestors(chia_root: ChiaRoot, wallet_node):
root = chia_root.path
config = load_config(root, "config.yaml")
config["data_layer"]["database_path"] = "data_layer_test.sqlite"
wallet = wallet_node[1][0][0]
data_layer = DataLayer(
config["data_layer"],
root_path=root,
wallet_state_manager=wallet.wallet_state_manager,
consensus_constants=DEFAULT_CONSTANTS,
)
connection = await aiosqlite.connect(data_layer.db_path)
data_layer.connection = connection
data_layer.db_wrapper = DBWrapper(data_layer.connection)
data_layer.data_store = await DataStore.create(data_layer.db_wrapper)
data_layer.initialized = True
rpc_api = DataLayerRpcApi(data_layer)
key1 = b"a"
value1 = b"\x01\x02"
changelist: List[Dict[str, str]] = [{"action": "insert", "key": key1.hex(), "value": value1.hex()}]
key2 = b"b"
value2 = b"\x03\x02"
changelist.append({"action": "insert", "key": key2.hex(), "value": value2.hex()})
key3 = b"c"
value3 = b"\x04\x05"
changelist.append({"action": "insert", "key": key3.hex(), "value": value3.hex()})
key4 = b"d"
value4 = b"\x06\x03"
changelist.append({"action": "insert", "key": key4.hex(), "value": value4.hex()})
key5 = b"e"
value5 = b"\x07\x01"
changelist.append({"action": "insert", "key": key5.hex(), "value": value5.hex()})
res = await rpc_api.create_kv_store()
tree_id = bytes32(hexstr_to_bytes(res["id"]))
await rpc_api.update_kv_store({"id": tree_id.hex(), "changelist": changelist})
val = await rpc_api.get_ancestors({"id": tree_id.hex(), "key": key1.hex()})
# todo assert values
await connection.close()