Merge branch 'main' into Pravdyvy/indexer-state-management

This commit is contained in:
Pravdyvy 2026-02-11 15:53:01 +02:00
commit e5f908d241
10 changed files with 777 additions and 416 deletions

3
.gitignore vendored
View File

@ -7,4 +7,5 @@ data/
.vscode/
rocksdb
sequencer_runner/data/
storage.json
storage.json
result

933
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -150,10 +150,11 @@ _wallet_account() {
subcommand)
subcommands=(
'get:Get account data'
'list:List all accounts'
'list:List all accounts owned by the wallet'
'ls:List all accounts (alias for list)'
'new:Produce new public or private account'
'sync-private:Sync private accounts'
'label:Set a label for an account'
'help:Print this message or the help of the given subcommand(s)'
)
_describe -t subcommands 'account subcommands' subcommands
@ -184,6 +185,11 @@ _wallet_account() {
;;
esac
;;
label)
_arguments \
'(-a --account-id)'{-a,--account-id}'[Account ID to label]:account_id:_wallet_account_ids' \
'(-l --label)'{-l,--label}'[The label to assign to the account]:label:'
;;
esac
;;
esac

View File

@ -2,6 +2,7 @@
name = "explorer_service"
version = "0.1.0"
edition = "2024"
license.workspace = true
[lib]
crate-type = ["cdylib", "rlib"]

View File

@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
pub struct SearchResults {
pub blocks: Vec<Block>,
pub transactions: Vec<Transaction>,
pub accounts: Vec<(AccountId, Account)>,
pub accounts: Vec<(AccountId, Option<Account>)>,
}
/// RPC client type
@ -60,8 +60,14 @@ pub async fn search(query: String) -> Result<SearchResults, ServerFnError> {
// Try as account ID
let account_id = AccountId { value: hash_array };
if let Ok(account) = client.get_account(account_id).await {
accounts.push((account_id, account));
match client.get_account(account_id).await {
Ok(account) => {
accounts.push((account_id, Some(account)));
}
Err(_) => {
// Account might not exist yet, still add it to results
accounts.push((account_id, None));
}
}
}

View File

@ -6,7 +6,7 @@ use crate::format_utils;
/// Account preview component
#[component]
pub fn AccountPreview(account_id: AccountId, account: Account) -> impl IntoView {
pub fn AccountPreview(account_id: AccountId, account: Option<Account>) -> impl IntoView {
let account_id_str = format_utils::format_account_id(&account_id);
view! {
@ -19,31 +19,42 @@ pub fn AccountPreview(account_id: AccountId, account: Account) -> impl IntoView
</div>
</div>
{move || {
let Account { program_owner, balance, data, nonce } = &account;
let program_id = format_utils::format_program_id(program_owner);
view! {
<div class="account-preview-body">
<div class="account-field">
<span class="field-label">"Balance: "</span>
<span class="field-value">{balance.to_string()}</span>
</div>
<div class="account-field">
<span class="field-label">"Program: "</span>
<span class="field-value hash">{program_id}</span>
</div>
<div class="account-field">
<span class="field-label">"Nonce: "</span>
<span class="field-value">{nonce.to_string()}</span>
</div>
<div class="account-field">
<span class="field-label">"Data: "</span>
<span class="field-value">
{format!("{} bytes", data.0.len())}
</span>
</div>
</div>
}
.into_any()
account
.as_ref()
.map(|Account { program_owner, balance, data, nonce }| {
let program_id = format_utils::format_program_id(program_owner);
view! {
<div class="account-preview-body">
<div class="account-field">
<span class="field-label">"Balance: "</span>
<span class="field-value">{balance.to_string()}</span>
</div>
<div class="account-field">
<span class="field-label">"Program: "</span>
<span class="field-value hash">{program_id}</span>
</div>
<div class="account-field">
<span class="field-label">"Nonce: "</span>
<span class="field-value">{nonce.to_string()}</span>
</div>
<div class="account-field">
<span class="field-label">"Data: "</span>
<span class="field-value">
{format!("{} bytes", data.0.len())}
</span>
</div>
</div>
}
.into_any()
})
.unwrap_or_else(|| {
view! {
<div class="account-preview-body">
<div class="account-not-found">"Account not found"</div>
</div>
}
.into_any()
})
}}
</A>

64
flake.lock generated Normal file
View File

@ -0,0 +1,64 @@
{
"nodes": {
"crane": {
"locked": {
"lastModified": 1769737823,
"narHash": "sha256-DrBaNpZ+sJ4stXm+0nBX7zqZT9t9P22zbk6m5YhQxS4=",
"owner": "ipetkov",
"repo": "crane",
"rev": "b2f45c3830aa96b7456a4c4bc327d04d7a43e1ba",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1770019141,
"narHash": "sha256-VKS4ZLNx4PNrABoB0L8KUpc1fE7CLpQXQs985tGfaCU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "cb369ef2efd432b3cdf8622b0ffc0a97a02f3137",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"crane": "crane",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1770088046,
"narHash": "sha256-4hfYDnUTvL1qSSZEA4CEThxfz+KlwSFQ30Z9jgDguO0=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "71f9daa4e05e49c434d08627e755495ae222bc34",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

96
flake.nix Normal file
View File

@ -0,0 +1,96 @@
{
description = "Logos Execution Zone";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
crane.url = "github:ipetkov/crane";
};
outputs =
{
self,
nixpkgs,
rust-overlay,
crane,
...
}:
let
systems = [
"x86_64-linux"
"aarch64-linux"
"aarch64-darwin"
"x86_64-windows"
];
forAll = nixpkgs.lib.genAttrs systems;
mkPkgs =
system:
import nixpkgs {
inherit system;
overlays = [ rust-overlay.overlays.default ];
};
in
{
packages = forAll (
system:
let
pkgs = mkPkgs system;
rustToolchain = pkgs.rust-bin.stable.latest.default;
craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain;
src = ./.;
commonArgs = {
inherit src;
buildInputs = [ pkgs.openssl ];
nativeBuildInputs = [
pkgs.pkg-config
pkgs.clang
pkgs.llvmPackages.libclang.lib
];
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
};
walletFfiPackage = craneLib.buildPackage (
commonArgs
// {
pname = "logos-execution-zone-wallet-ffi";
version = "0.1.0";
cargoExtraArgs = "-p wallet-ffi";
postInstall = ''
mkdir -p $out/include
cp wallet-ffi/wallet_ffi.h $out/include/
''
+ pkgs.lib.optionalString pkgs.stdenv.isDarwin ''
install_name_tool -id @rpath/libwallet_ffi.dylib $out/lib/libwallet_ffi.dylib
'';
}
);
in
{
wallet = walletFfiPackage;
default = walletFfiPackage;
}
);
devShells = forAll (
system:
let
pkgs = mkPkgs system;
walletFfiPackage = self.packages.${system}.wallet;
walletFfiShell = pkgs.mkShell {
inputsFrom = [ walletFfiPackage ];
};
in
{
wallet = walletFfiShell;
default = walletFfiShell;
}
);
};
}

View File

@ -211,6 +211,13 @@ impl indexer_service_rpc::RpcServer for MockIndexerService {
.ok_or_else(|| ErrorObjectOwned::owned(-32001, "Block with hash not found", None::<()>))
}
async fn get_last_block_id(&self) -> Result<BlockId, ErrorObjectOwned> {
self.blocks
.last()
.map(|b| b.header.block_id)
.ok_or_else(|| ErrorObjectOwned::owned(-32001, "No blocks available", None::<()>))
}
async fn get_account(&self, account_id: AccountId) -> Result<Account, ErrorObjectOwned> {
self.accounts
.get(&account_id)

View File

@ -1,9 +1,9 @@
{
"override_rust_log": null,
"sequencer_addr": "http://127.0.0.1:3040",
"seq_poll_timeout_millis": 12000,
"seq_tx_poll_max_blocks": 5,
"seq_poll_max_retries": 5,
"seq_poll_timeout_millis": 30000,
"seq_tx_poll_max_blocks": 15,
"seq_poll_max_retries": 10,
"seq_block_poll_max_amount": 100,
"initial_accounts": [
{