Skip to content

Commit

Permalink
Merge branch 'dr/terminal-userspace-api' into dr/settings-userspace-api
Browse files Browse the repository at this point in the history
Conflicts:
      kinode/packages/settings/settings/src/lib.rs
  • Loading branch information
nick1udwig committed Dec 20, 2024
2 parents 34694bc + 57a32ee commit a393b2a
Show file tree
Hide file tree
Showing 79 changed files with 744 additions and 280 deletions.
24 changes: 23 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ members = [
"kinode/packages/chess/chess",
"kinode/packages/contacts/contacts",
"kinode/packages/homepage/homepage",
"kinode/packages/kns-indexer/kns-indexer", "kinode/packages/kns-indexer/get-block", "kinode/packages/settings/settings",
"kinode/packages/kns-indexer/kns-indexer", "kinode/packages/kns-indexer/get-block", "kinode/packages/settings/settings", "kinode/packages/kns-indexer/reset",
"kinode/packages/kns-indexer/node-info",
"kinode/packages/terminal/terminal",
"kinode/packages/terminal/alias", "kinode/packages/terminal/cat", "kinode/packages/terminal/echo",
"kinode/packages/terminal/help", "kinode/packages/terminal/hi", "kinode/packages/terminal/kfetch",
Expand Down
2 changes: 1 addition & 1 deletion kinode/packages/app-store/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions kinode/packages/app-store/api/app-store:sys-v1.wit
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ interface chain {
///
/// lazy-load-blob: none.
stop-auto-update(package-id),
/// Reset app-store db
///
/// lazy-load-blob: none.
reset,
}

/// Responses from the chain component
Expand All @@ -149,6 +153,8 @@ interface chain {
/// lazy-load-blob: none.
auto-update-stopped,
/// lazy-load-blob: none.
/// successful reset
reset-ok,
err(chain-error),
}

Expand Down
2 changes: 1 addition & 1 deletion kinode/packages/app-store/app-store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ alloy-primitives = "0.8.15"
alloy-sol-types = "0.8.15"
anyhow = "1.0"
bincode = "1.3.3"
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "d97e012" }
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "ea8490a" }
process_macros = "0.1"
rand = "0.8"
serde = { version = "1.0", features = ["derive"] }
Expand Down
23 changes: 23 additions & 0 deletions kinode/packages/app-store/app-store/src/http_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub fn init_frontend(our: &Address, http_server: &mut server::HttpServer) {
"/apps/:id/install", // install a downloaded app
"/downloads/:id/mirror", // start mirroring a version of a downloaded app
"/downloads/:id/remove", // remove a downloaded app
"/reset", // reset chain state, re-index
"/apps/:id/auto-update", // set auto-updating a version of a downloaded app
"/updates/:id/clear", // clear update info for an app.
"/mirrorcheck/:node", // check if a node/mirror is online/offline
Expand Down Expand Up @@ -726,6 +727,28 @@ fn serve_paths(
updates.save();
Ok((StatusCode::OK, None, vec![]))
}
// POST reset chain state, re-index
"/reset" => {
if method != Method::POST {
return Ok((
StatusCode::METHOD_NOT_ALLOWED,
None,
format!("Invalid method {method} for {bound_path}").into_bytes(),
));
}
let chain = Address::from_str("our@chain:app-store:sys")?;

let resp = Request::new()
.target(chain)
.body(&ChainRequests::Reset)
.send_and_await_response(5)??;
let msg = serde_json::from_slice::<ChainResponses>(resp.body())?;
if let ChainResponses::ResetOk = msg {
Ok((StatusCode::OK, None, vec![]))
} else {
Ok((StatusCode::INTERNAL_SERVER_ERROR, None, vec![]))
}
}
// GET online/offline mirrors for a listed app
"/mirrorcheck/:node" => {
if method != Method::GET {
Expand Down
2 changes: 1 addition & 1 deletion kinode/packages/app-store/chain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ alloy-primitives = "0.8.15"
alloy-sol-types = "0.8.15"
anyhow = "1.0"
bincode = "1.3.3"
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "d97e012" }
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "ea8490a" }
process_macros = "0.1"
rand = "0.8"
serde = { version = "1.0", features = ["derive"] }
Expand Down
39 changes: 27 additions & 12 deletions kinode/packages/app-store/chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ impl DB {
Ok(Self { inner })
}

pub fn reset(&self, our: &Address) {
if let Err(e) = sqlite::remove_db(our.package_id(), "app_store_chain.sqlite", None) {
println!("failed to reset app_store DB: {e}");
}
}

pub fn get_last_saved_block(&self) -> anyhow::Result<u64> {
let query = "SELECT value FROM meta WHERE key = 'last_saved_block'";
let rows = self.inner.read(query.into(), vec![])?;
Expand All @@ -121,7 +127,7 @@ impl DB {
}

pub fn set_last_saved_block(&self, block: u64) -> anyhow::Result<()> {
let query = "INSERT INTO meta (key, value) VALUES ('last_saved_block', ?)
let query = "INSERT INTO meta (key, value) VALUES ('last_saved_block', ?)
ON CONFLICT(key) DO UPDATE SET value=excluded.value";
let params = vec![block.to_string().into()];
self.inner.write(query.into(), params, None)?;
Expand All @@ -141,12 +147,12 @@ impl DB {

let query = "INSERT INTO listings (package_name, publisher_node, tba, metadata_uri, metadata_hash, metadata_json, auto_update, block)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(package_name, publisher_node)
DO UPDATE SET
tba=excluded.tba,
metadata_uri=excluded.metadata_uri,
metadata_hash=excluded.metadata_hash,
metadata_json=excluded.metadata_json,
ON CONFLICT(package_name, publisher_node)
DO UPDATE SET
tba=excluded.tba,
metadata_uri=excluded.metadata_uri,
metadata_hash=excluded.metadata_hash,
metadata_json=excluded.metadata_json,
auto_update=excluded.auto_update,
block=excluded.block";
let params = vec![
Expand Down Expand Up @@ -234,7 +240,7 @@ impl DB {
block_number: u64,
) -> anyhow::Result<Vec<(PackageId, PackageListing)>> {
let query = "SELECT package_name, publisher_node, tba, metadata_uri, metadata_hash, metadata_json, auto_update, block
FROM listings
FROM listings
WHERE block > ?";
let params = vec![block_number.into()];
let rows = self.inner.read(query.into(), params)?;
Expand Down Expand Up @@ -415,19 +421,23 @@ fn handle_message(our: &Address, state: &mut State, message: &Message) -> anyhow
state
.kimap
.provider
.subscribe_loop(1, app_store_filter(state));
.subscribe_loop(1, app_store_filter(state), 1, 0);
}
}
Req::Request(chains) => {
handle_local_request(state, chains)?;
handle_local_request(our, state, chains)?;
}
}
}

Ok(())
}

fn handle_local_request(state: &mut State, req: ChainRequests) -> anyhow::Result<()> {
fn handle_local_request(
our: &Address,
state: &mut State,
req: ChainRequests,
) -> anyhow::Result<()> {
match req {
ChainRequests::GetApp(package_id) => {
let pid = package_id.clone().to_process_lib();
Expand Down Expand Up @@ -480,6 +490,11 @@ fn handle_local_request(state: &mut State, req: ChainRequests) -> anyhow::Result
Response::new().body(&error_response).send()?;
}
}
ChainRequests::Reset => {
state.db.reset(&our);
Response::new().body(&ChainResponses::ResetOk).send()?;
panic!("resetting state, restarting!");
}
}
Ok(())
}
Expand Down Expand Up @@ -746,7 +761,7 @@ pub fn fetch_and_subscribe_logs(our: &Address, state: &mut State, last_saved_blo
let filter = app_store_filter(state);
// get past logs, subscribe to new ones.
// subscribe first so we don't miss any logs
state.kimap.provider.subscribe_loop(1, filter.clone());
state.kimap.provider.subscribe_loop(1, filter.clone(), 1, 0);
// println!("fetching old logs from block {last_saved_block}");
for log in fetch_logs(&state.kimap.provider, &filter.from_block(last_saved_block)) {
if let Err(e) = handle_eth_log(our, state, log, true) {
Expand Down
2 changes: 1 addition & 1 deletion kinode/packages/app-store/download/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ simulation-mode = []

[dependencies]
anyhow = "1.0"
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "d97e012" }
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "ea8490a" }
process_macros = "0.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Expand Down
2 changes: 1 addition & 1 deletion kinode/packages/app-store/downloads/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ simulation-mode = []

[dependencies]
anyhow = "1.0"
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "d97e012" }
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "ea8490a" }
process_macros = "0.1"
rand = "0.8"
serde = { version = "1.0", features = ["derive"] }
Expand Down
4 changes: 1 addition & 3 deletions kinode/packages/app-store/downloads/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ impl State {

call_init!(init);
fn init(our: Address) {
println!("downloads: started");

// mirroring metadata is separate from vfs downloads state.
let mut state = State::load();

Expand Down Expand Up @@ -452,7 +450,7 @@ fn handle_message(
.iter()
.find(|(version, _)| version == &current_version)
.map(|(_, hash)| hash.clone())
// note, if this errors, full on failure I thnk no?
// note, if this errors, full on failure I thnk no?
// and bubble this up.
.ok_or_else(|| anyhow::anyhow!("auto_update: error for package_id: {}, current_version: {}, no matching hash found", process_lib_package_id.to_string(), current_version))?;

Expand Down
2 changes: 1 addition & 1 deletion kinode/packages/app-store/ft-worker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ simulation-mode = []
[dependencies]
anyhow = "1.0"
bincode = "1.3.3"
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "d97e012" }
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "ea8490a" }
process_macros = "0.1"
rand = "0.8"
serde = { version = "1.0", features = ["derive"] }
Expand Down
2 changes: 1 addition & 1 deletion kinode/packages/app-store/install/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ simulation-mode = []

[dependencies]
anyhow = "1.0"
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "d97e012" }
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "ea8490a" }
process_macros = "0.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Expand Down
69 changes: 69 additions & 0 deletions kinode/packages/app-store/ui/src/components/ResetButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useState } from 'react';
import { FaExclamationTriangle } from 'react-icons/fa';
import useAppsStore from '../store';

const ResetButton: React.FC = () => {
const resetStore = useAppsStore(state => state.resetStore);
const [isOpen, setIsOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);

const handleReset = async () => {
try {
setIsLoading(true);
await resetStore();
setIsOpen(false);
} catch (error) {
console.error('Reset failed:', error);
alert('Failed to reset the app store. Please try again.');
} finally {
setIsLoading(false);
}
};

return (
<>
<button
onClick={() => setIsOpen(true)}
className="button danger"
style={{ fontSize: '0.9rem' }}
>
Reset Store
</button>

{isOpen && (
<div className="modal-overlay" onClick={() => setIsOpen(false)}>
<div className="modal-content" onClick={e => e.stopPropagation()}>
<button className="modal-close" onClick={() => setIsOpen(false)}>×</button>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem', marginBottom: '1rem' }}>
<FaExclamationTriangle size={24} style={{ color: 'var(--red)' }} />
<h3 style={{ margin: 0 }}>Warning</h3>
</div>

<p style={{ marginBottom: '1.5rem' }}>
This action will re-index all apps and reset the store state.
Only proceed if you know what you're doing.
</p>

<div style={{ display: 'flex', justifyContent: 'flex-end', gap: '0.75rem' }}>
<button
onClick={() => setIsOpen(false)}
className="button"
>
Cancel
</button>
<button
onClick={handleReset}
disabled={isLoading}
className="button danger"
>
{isLoading ? 'Resetting...' : 'Reset Store'}
</button>
</div>
</div>
</div>
)}
</>
);
};

export default ResetButton;
3 changes: 2 additions & 1 deletion kinode/packages/app-store/ui/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export { default as Header } from './Header';
export { default as MirrorSelector } from './MirrorSelector';
export { default as PackageSelector } from './PackageSelector';
export { default as ManifestDisplay } from './ManifestDisplay';
export { default as NotificationBay } from './NotificationBay';
export { default as NotificationBay } from './NotificationBay';
export { default as ResetButton } from './ResetButton';
Loading

0 comments on commit a393b2a

Please sign in to comment.