diff --git a/Cargo.lock b/Cargo.lock index ba76a973..2ee636b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4467,6 +4467,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "state" +version = "0.1.0" +dependencies = [ + "kinode_process_lib 0.6.0 (git+https://github.com/kinode-dao/process_lib?tag=v0.6.0-alpha.2)", + "serde", + "serde_json", + "wit-bindgen", +] + [[package]] name = "static_assertions" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index c3793117..aef2f9a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ members = [ "kinode/packages/app_store/download", "kinode/packages/app_store/install", "kinode/packages/app_store/uninstall", "kinode/packages/chess/chess", "kinode/packages/homepage/homepage", - "kinode/packages/kns_indexer/kns_indexer", "kinode/packages/kns_indexer/get_block", + "kinode/packages/kns_indexer/kns_indexer", "kinode/packages/kns_indexer/get_block", "kinode/packages/kns_indexer/state", "kinode/packages/terminal/terminal", "kinode/packages/terminal/alias", "kinode/packages/terminal/cat", "kinode/packages/terminal/echo", "kinode/packages/terminal/hi", "kinode/packages/terminal/m", "kinode/packages/terminal/top", "kinode/packages/terminal/namehash_to_name", "kinode/packages/terminal/net_diagnostics", "kinode/packages/terminal/peer", "kinode/packages/terminal/peers", diff --git a/kinode/packages/kns_indexer/kns_indexer/src/lib.rs b/kinode/packages/kns_indexer/kns_indexer/src/lib.rs index 3269949e..09553758 100644 --- a/kinode/packages/kns_indexer/kns_indexer/src/lib.rs +++ b/kinode/packages/kns_indexer/kns_indexer/src/lib.rs @@ -45,7 +45,11 @@ pub enum IndexerRequests { NamehashToName { hash: String, block: u64 }, /// return the most recent on-chain routing information for a node name. /// returns an Option + /// set block to 0 if you just want to get the current state of the indexer NodeInfo { name: String, block: u64 }, + /// return the entire state of the indexer at the given block + /// set block to 0 if you just want to get the current state of the indexer + GetState { block: u64 }, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -276,6 +280,16 @@ fn main(our: Address, mut state: State) -> anyhow::Result<()> { .push(request); } } + IndexerRequests::GetState { block } => { + if block <= state.block { + Response::new().body(serde_json::to_vec(&state)?).send()?; + } else { + pending_requests + .entry(block) + .or_insert(vec![]) + .push(request); + } + } } } } @@ -324,6 +338,12 @@ fn handle_eth_message( .send() .unwrap(); } + IndexerRequests::GetState { .. } => { + Response::new() + .body(serde_json::to_vec(&state)?) + .send() + .unwrap(); + } } } blocks_to_remove.push(*block); diff --git a/kinode/packages/kns_indexer/pkg/scripts.json b/kinode/packages/kns_indexer/pkg/scripts.json index 8d4119ca..0fe08a0d 100644 --- a/kinode/packages/kns_indexer/pkg/scripts.json +++ b/kinode/packages/kns_indexer/pkg/scripts.json @@ -9,5 +9,16 @@ "grant_capabilities": [ "eth:distro:sys" ] + }, + "state.wasm": { + "root": false, + "public": false, + "request_networking": false, + "request_capabilities": [ + "kns_indexer:kns_indexer:sys" + ], + "grant_capabilities": [ + "kns_indexer:kns_indexer:sys" + ] } } \ No newline at end of file diff --git a/kinode/packages/kns_indexer/state/Cargo.toml b/kinode/packages/kns_indexer/state/Cargo.toml new file mode 100644 index 00000000..61d0cbe1 --- /dev/null +++ b/kinode/packages/kns_indexer/state/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "state" +version = "0.1.0" +edition = "2021" + + +[dependencies] +kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", tag = "v0.6.0-alpha.2" } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "21a46c7" } + +[lib] +crate-type = ["cdylib"] + +[package.metadata.component] +package = "kinode:process" diff --git a/kinode/packages/kns_indexer/state/src/lib.rs b/kinode/packages/kns_indexer/state/src/lib.rs new file mode 100644 index 00000000..1755b819 --- /dev/null +++ b/kinode/packages/kns_indexer/state/src/lib.rs @@ -0,0 +1,72 @@ +use kinode_process_lib::{call_init, println, Address, Message, Request}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +wit_bindgen::generate!({ + path: "wit", + world: "process", + exports: { + world: Component, + }, +}); + +/// From main kns_indexer process +#[derive(Clone, Debug, Serialize, Deserialize)] +struct State { + chain_id: u64, + // what contract this state pertains to + contract_address: String, + // namehash to human readable name + names: HashMap, + // human readable name to most recent on-chain routing information as json + // NOTE: not every namehash will have a node registered + nodes: HashMap, + // last block we have an update from + block: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct KnsUpdate { + pub name: String, // actual username / domain name + pub owner: String, + pub node: String, // hex namehash of node + pub public_key: String, + pub ip: String, + pub port: u16, + pub routers: Vec, +} + +call_init!(init); + +fn init(_our: Address) { + let Ok(Message::Response { body, .. }) = + Request::to(("our", "kns_indexer", "kns_indexer", "sys")) + .body( + serde_json::json!({ + "GetState": { + "block": 0 + } + }) + .to_string() + .as_bytes() + .to_vec(), + ) + .send_and_await_response(10) + .unwrap() + else { + println!("failed to get state from kns_indexer"); + return; + }; + let state = serde_json::from_slice::(&body).expect("failed to deserialize state"); + // can change later, but for now, just print every known node name + let mut names = state.names.values().map(AsRef::as_ref).collect::>(); + names.sort(); + println!( + "\nrunning on chain id {}\nCA: {}\n{} known nodes as of block {}\n {}", + state.chain_id, + state.contract_address, + names.len(), + state.block, + names.join("\n ") + ); +}