Skip to content

Commit

Permalink
Improve CLI and docs (paritytech#53)
Browse files Browse the repository at this point in the history
* Improve CLI

- Add `--version` option.
- Move `--no-hardware-benchmarks` to run cmd.
- Improve cli help.

* Revamp docs

* Add docs/src/dumptxoutset.md

* Make .content main more friendly for wider screen

* More css style update

* Update docs

* Add architecture.md

* .
  • Loading branch information
liuchengxu authored Sep 15, 2024
1 parent 77a86db commit 1b2067c
Show file tree
Hide file tree
Showing 15 changed files with 2,457 additions and 53 deletions.
10 changes: 7 additions & 3 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,22 @@ jobs:
restore-keys: |
${{ runner.os }}-cargo-
- name: Install mdbook and mdbook-mermaid
run: |
cargo install mdbook --version 0.4.40
cargo install mdbook-mermaid --version 0.14.0
- name: Build Rustdoc
run: cargo +${{ env.RUST_TOOLCHAIN }} -Zgitoxide -Zgit doc --all --no-deps --lib
env:
RUSTDOCFLAGS: "-Z unstable-options --enable-index-page"

- name: Build User Guide
- name: Build Book
run: |
cargo install --vers "^0.4" mdbook
mdbook build docs && mdbook test docs
mv docs/book target/doc
- name: Deploy Docs
- name: Deploy Docs (Rustdoc and Book)
uses: JamesIves/github-pages-deploy-action@v4
with:
branch: gh-pages
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div align="center">

<p align="center"><img width="400" src="./docs/images/subcoin-high-resolution-logo.png" alt="Subcoin logo"></p>
<p align="center"><img width="400" src="./docs/src/images/subcoin-high-resolution-logo.png" alt="Subcoin logo"></p>

[![Continuous integration](https://github.com/subcoin-project/subcoin/actions/workflows/ci.yml/badge.svg)](https://github.com/subcoin-project/subcoin/actions/workflows/ci.yml)
[![Docs](https://github.com/subcoin-project/subcoin/actions/workflows/docs.yml/badge.svg)](https://github.com/subcoin-project/subcoin/actions/workflows/docs.yml)
Expand Down
19 changes: 4 additions & 15 deletions crates/subcoin-node/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,13 @@ pub enum Command {
ChainInfo(sc_cli::ChainInfoCmd),
}

/// Subcoin Client Node
#[derive(Debug, Parser)]
#[clap(version = env!("SUBSTRATE_CLI_IMPL_VERSION"))]
pub struct Cli {
#[command(subcommand)]
pub command: Command,

/// Disable automatic hardware benchmarks.
///
/// By default these benchmarks are automatically ran at startup and measure
/// the CPU speed, the memory bandwidth and the disk speed.
///
/// The results are then printed out in the logs, and also sent as part of
/// telemetry, if telemetry is enabled.
#[arg(long)]
pub no_hardware_benchmarks: bool,

#[allow(missing_docs)]
#[clap(flatten)]
pub storage_monitor: sc_storage_monitor::StorageMonitorParams,
Expand All @@ -80,7 +72,6 @@ pub struct Cli {
pub fn run() -> sc_cli::Result<()> {
let Cli {
command,
no_hardware_benchmarks,
storage_monitor,
} = Cli::parse();

Expand All @@ -89,9 +80,7 @@ pub fn run() -> sc_cli::Result<()> {
let run_cmd = RunCmd::new(*run);
let runner = SubstrateCli.create_runner(&run_cmd)?;
runner.run_node_until_exit(|config| async move {
run_cmd
.start(config, no_hardware_benchmarks, storage_monitor)
.await
run_cmd.start(config, storage_monitor).await
})
}
Command::ImportBlocks(cmd) => {
Expand All @@ -118,7 +107,7 @@ pub fn run() -> sc_cli::Result<()> {
network: bitcoin_network,
config: &config,
block_execution_strategy,
no_hardware_benchmarks,
no_hardware_benchmarks: true,
storage_monitor,
})?;
let spawn_handle = task_manager.spawn_handle();
Expand Down
13 changes: 11 additions & 2 deletions crates/subcoin-node/src/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ pub struct Run {
#[clap(long)]
pub disable_subcoin_networking: bool,

/// Disable automatic hardware benchmarks.
///
/// By default these benchmarks are automatically ran at startup and measure
/// the CPU speed, the memory bandwidth and the disk speed.
///
/// The results are then printed out in the logs, and also sent as part of
/// telemetry, if telemetry is enabled.
#[arg(long)]
pub no_hardware_benchmarks: bool,

#[allow(missing_docs)]
#[clap(flatten)]
pub rpc_params: RpcParams,
Expand Down Expand Up @@ -92,7 +102,6 @@ impl RunCmd {
pub async fn start(
self,
mut config: Configuration,
no_hardware_benchmarks: bool,
storage_monitor: sc_storage_monitor::StorageMonitorParams,
) -> sc_cli::Result<TaskManager> {
let Self {
Expand All @@ -116,7 +125,7 @@ impl RunCmd {
network: bitcoin_network,
config: &config,
block_execution_strategy,
no_hardware_benchmarks,
no_hardware_benchmarks: run.no_hardware_benchmarks,
storage_monitor,
})?;

Expand Down
9 changes: 8 additions & 1 deletion docs/book.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[book]
title = "Subcoin"
title = "Subcoin Book"
authors = ["Liu-Cheng Xu"]
language = "en"
description = "A comprehensive guide to Subcoin, a Bitcoin Node in Substrate."
Expand All @@ -10,6 +10,13 @@ src = "src"
edition = "2021"

[output.html]
additional-css =["src/css/custom.css"]
git-repository-url = "https://github.com/subcoin-project/subcoin"
git-repository-icon = "fa-github"
edit-url-template = "https://github.com/subcoin-project/subcoin/edit/main/docs/{path}"
additional-js = ["mermaid.min.js", "mermaid-init.js"]

[preprocessor]

[preprocessor.mermaid]
command = "mdbook-mermaid"
35 changes: 35 additions & 0 deletions docs/mermaid-init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
(() => {
const darkThemes = ['ayu', 'navy', 'coal'];
const lightThemes = ['light', 'rust'];

const classList = document.getElementsByTagName('html')[0].classList;

let lastThemeWasLight = true;
for (const cssClass of classList) {
if (darkThemes.includes(cssClass)) {
lastThemeWasLight = false;
break;
}
}

const theme = lastThemeWasLight ? 'default' : 'dark';
mermaid.initialize({ startOnLoad: true, theme });

// Simplest way to make mermaid re-render the diagrams in the new theme is via refreshing the page

for (const darkTheme of darkThemes) {
document.getElementById(darkTheme).addEventListener('click', () => {
if (lastThemeWasLight) {
window.location.reload();
}
});
}

for (const lightTheme of lightThemes) {
document.getElementById(lightTheme).addEventListener('click', () => {
if (!lastThemeWasLight) {
window.location.reload();
}
});
}
})();
2,186 changes: 2,186 additions & 0 deletions docs/mermaid.min.js

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

[Introduction](README.md)

# Dev Guide

- [Architecture](architecture.md)

# User Guide

- [Installation](installation.md)
- [Usage](usage.md)
- [Run a Node](run-a-node.md)
- [Import Bitcoin Core Blocks](import-bitcoind-blocks.md)
- [Export Bitcoin State](dumptxoutset.md)
40 changes: 40 additions & 0 deletions docs/src/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Architecture

## Overview

<img src="./images/Derive-Subcoin-from-Bitcoin.png" alt="Derive text" style="max-width: 600px; width: 100%; display: block; margin: 0 auto;">

Subcoin operates similarly to how a Layer 2 chain is derived from a Layer 1 chain in a modular blockchain architecture. Each Subcoin block is deterministically derived from the corresponding Bitcoin block at the same height, faithfully replicating Bitcoin's transaction logic (Money Transfer).

The Bitcoin state (UTXO Set) is embedded within the Subcoin state, which includes a commitment to the global chain state (`state_root`). Effectively, Subcoin functions like Bitcoin with an added state root for the global Bitcoin state. This `state_root` enables possibilities like decentralized fast sync, without requiring any modifications to the Bitcoin protocol.

Additionally, Subcoin serves as an ideal testbed for new Bitcoin features, which are often challenging to land on the Bitcoin mainnet due to its stability and conservative development process. Developers can experiment with new innovations and features on Subcoin in a live environment without affecting the Bitcoin mainnet.

Subcoin is not a new blockchain but a replica of the Bitcoin chain with additional functionality, such as decentralized fast sync and flexibility for testing new features.

## Code Map

This section provides a brief overview of key directories and data structures in the project.

### `crates/pallet-bitcoin`

This pallet is responsible for tracking the state of the UTXO Set. Transaction verification is deliberately excluded from this pallet, with all verifications handled on the client side through `sc-consensus-nakamoto`.

### `crates/sc-consensus-nakamoto`

This crate manages the processing and importing of Bitcoin blocks into the database, whether they are sourced from a local Bitcoin Core database or downloaded via the P2P network.

- `BitcoinBlockImporter`: Processes and imports blocks into the database.
- `BlockImportQueue`: Bridges blocks downloaded from the Bitcoin P2P network to BitcoinBlockImporter.

### `crates/subcoin-network`

This crate handles downloading Bitcoin blocks from the Bitcoin P2P network. The downloaded blocks are sent to the import queue, running in a separate task for processing. Block processing results are communicated back to ensure seamless integration.

### `crates/subcoin-runtime`

This is a minimal Substrate runtime, composed of `frame-system` and `pallet-bitcoin`, which defines the core business logic of Subcoin chain.

### `crates/subcoin-node`

The entry point for the Subcoin node is located at `crates/subcoin-node/src/bin/subcoin.rs`, which initializes and runs the node.
109 changes: 109 additions & 0 deletions docs/src/css/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
.warning {
margin: 0px;
}

/* Increase the width for wider screens while maintaining a max-width for readability */
.content main {
max-width: 900px; /* Adjust the max width as needed */
width: 90%; /* Let the width be responsive to the screen size */
margin: 0 auto; /* Center the content */
}

/* Optional: improve readability by slightly adjusting the line height and padding */
.content {
line-height: 1.6; /* Increase line height for better readability */
padding: 20px; /* Add some padding for a better look */
}

/* Add some spacing for mobile screens */
@media (max-width: 768px) {
.content main {
max-width: 100%; /* Make it full-width on smaller screens */
}
}

/* Set a gradient background for the main content */
body {
background: linear-gradient(to right, #f0f0f0, #fafafa); /* Light gradient */
font-family: 'Roboto', sans-serif; /* Use a clean, modern font */
color: #333;
line-height: 1.8; /* Improve readability */
}

/* Header styling */
nav.navbar {
background-color: #343a40; /* Darker background for the header */
border-bottom: 2px solid #d63384; /* Add a border to make it pop */
color: white;
}

nav.navbar a {
color: #f8f9fa; /* Light text color */
padding: 10px 20px;
}

nav.navbar a:hover {
background-color: #495057; /* Slight hover effect */
}

/* Footer Styling */
footer {
background-color: #343a40;
color: #f8f9fa;
text-align: center;
padding: 10px 0;
font-size: 0.9em;
}

/* Dark Mode Styles */
body.dark-mode {
background-color: #212529;
color: #f8f9fa;
}

nav.navbar.dark-mode {
background-color: #1b1e21;
}

.sidebar.dark-mode {
background-color: #2b2f33;
}

button.dark-mode-toggle {
background-color: #495057;
color: #f8f9fa;
}

h1, h2, h3 {
font-family: 'Merriweather', serif; /* Elegant font for headers */
color: #d63384; /* Accent color for headings */
margin-top: 30px;
}

.sidebar {
width: 300px;
background-color: #f8f9fa; /* Light background for sidebar */
padding: 15px;
border-right: 1px solid #dee2e6;
}

/* Button Styling */
button, .btn {
background-color: #d63384; /* Accent color for buttons */
border: none;
color: white;
padding: 10px 15px;
border-radius: 5px;
font-size: 1em;
}

button:hover, .btn:hover {
background-color: #c12876; /* Darker shade on hover */
cursor: pointer;
}

h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
padding: .2em;
background-color: #818b981f;
border-radius: 6px;
}
17 changes: 17 additions & 0 deletions docs/src/dumptxoutset.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Export Bitcoin State Compatible with Bitcoin Core

## `dumptxoutset` Command

Subcoin provides the ability to export the Bitcoin state (UTXO Set) into a binary file that is fully compatible with the output of Bitcoin Core's `dumptxoutset` command, allowing for seamless integration and compatibility with Bitcoin Core.

To use this feature, check out this command:

```bash
subcoin blockchain dumptxoutset --help
```

## Decentralized UTXO Set Snapshot Download (Coming Soon)

You can download the Bitcoin state directly from the Subcoin P2P network in a fully decentralized manner, eliminating the need for trusted snapshot providers. This feature will allow you to retrieve the UTXO Set snapshot from the network, convert it into a format compatible with Bitcoin Core, and import it directly into a Bitcoin Core node. This makes Subcoin an ideal addition to the Bitcoin Core ecosystem, providing a decentralized, secure, and efficient method for syncing with Bitcoin’s UTXO set.

Follow [Subcoin Issue #54](https://github.com/subcoin-project/subcoin/issues/54) for this complementary feature, which will enhance the functionality of Bitcoin Core by integrating decentralized state retrieval from Subcoin.
Binary file added docs/src/images/Derive-Subcoin-from-Bitcoin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 1b2067c

Please sign in to comment.