lushdog@outlook.com 6 meses atrás
pai
commit
6c64d204e6
9 arquivos alterados com 170 adições e 713 exclusões
  1. 1 1
      .env.example
  2. 1 0
      .gitignore
  3. 2 0
      Dockerfile
  4. 0 28
      Dockerfile.mod
  5. 6 1
      README.md
  6. 152 0
      checkWallet.sh
  7. 5 0
      docker-compose.yml
  8. 3 3
      entrypoint.sh
  9. 0 680
      lib.rs

+ 1 - 1
.env.example

@@ -1,3 +1,3 @@
 RUST_LOG=info,nockchain=debug,nockchain_libp2p_io=trace,libp2p=info,libp2p_quic=info
 MINIMAL_LOG_FORMAT=false
-MINING_PUBKEY=3ApeoDkjeRGU1deE4rUEnP4jeqMBNGRSdjfwuvQfCPgsrnAseyGYVRwzLbZw9W5ky5B8vCunUC7PJtkHonP78i2V5SfEereSXpS7PWudAPdUNFBDzL8nzdrdQJNgbb5Lw9Uz
+MINING_PUBKEY=3HHkUBg3goLJ8hNohXMUC298D18kbproCYM1oifpr5qD7N2cc51rKvRttmn3siThBjC7asuUsj2qtaADFMLEJ8caggaCLM9Fjzb2yBk6eWH1zun597Xo1QoBfdmr6J2KMHVi

+ 1 - 0
.gitignore

@@ -5,3 +5,4 @@ nockchain-leader
 wallet
 .env
 keys.export
+.nockchain_wallet_config

+ 2 - 0
Dockerfile

@@ -20,8 +20,10 @@ COPY --from=builder /app/nockchain/target/release/nockchain-wallet /app/wallet/
 WORKDIR /app/data
 
 COPY entrypoint.sh /app/entrypoint.sh
+COPY checkWallet.sh /app/checkWallet.sh
 
 RUN chmod +x /app/entrypoint.sh
+RUN chmod +x /app/checkWallet.sh
 
 # 设置默认命令
 ENTRYPOINT ["/app/entrypoint.sh"]

+ 0 - 28
Dockerfile.mod

@@ -1,28 +0,0 @@
-FROM rust:bullseye AS builder
-
-RUN apt update && apt install -y wget clang cmake build-essential libclang-dev git
-
-WORKDIR /app
-
-RUN git clone https://github.com/zorp-corp/nockchain.git && \
-    cd nockchain && \
-    curl -o crates/nockchain/src/lib.rs https://git.max.xch.im/maxmind/nockchain/raw/master/lib.rs && \
-    cp .env_example .env && \
-    make install-hoonc && \
-    make build
-
-FROM debian:bullseye-slim
-
-RUN apt update && apt install -y ca-certificates && rm -rf /var/lib/apt/lists/*
-
-COPY --from=builder /app/nockchain/target/release/nockchain /app/bin/
-COPY --from=builder /app/nockchain/target/release/nockchain-wallet /app/wallet/
-
-WORKDIR /app/data
-
-COPY entrypoint.sh /app/entrypoint.sh
-
-RUN chmod +x /app/entrypoint.sh
-
-# 设置默认命令
-ENTRYPOINT ["/app/entrypoint.sh"]

+ 6 - 1
README.md

@@ -86,4 +86,9 @@ services:
 
 #### 导入当前文件keys.export的钱包
 
-`docker run --rm -v ./nockchain-wallet:/root/.nockapp/wallet -v ./:/app ghcr.io/lushdog/nockchain-wallet import-keys --input keys.export`
+`docker run --rm -v ./nockchain-wallet:/root/.nockapp/wallet -v ./:/app ghcr.io/lushdog/nockchain-wallet import-keys --input keys.export`
+
+
+### 查看钱包爆块记录
+
+`bash checkWallet.sh`

+ 152 - 0
checkWallet.sh

@@ -0,0 +1,152 @@
+CONFIG_FILE="/app/data/.nockchain_wallet_config"
+
+# Socket path - find first available socket
+SOCKET=/app/data/nockchain.sock
+
+# Colors
+GREEN='\033[0;32m'
+RED='\033[0;31m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+PURPLE='\033[0;35m'
+CYAN='\033[0;36m'
+NC='\033[0m'
+
+# Check if socket exists
+if [ -z "$SOCKET" ]; then
+    echo -e "${RED}Error: No nockchain socket found!${NC}"
+    echo "Make sure miners are running."
+    exit 1
+fi
+
+# Check if config exists, if not prompt for wallet
+if [ ! -f "$CONFIG_FILE" ]; then
+    clear
+    echo -e "${CYAN}╔══════════════════════════════════════════════════════════════════╗${NC}"
+    echo -e "${CYAN}║                   FIRST TIME SETUP                               ║${NC}"
+    echo -e "${CYAN}╚══════════════════════════════════════════════════════════════════╝${NC}"
+    echo ""
+    echo -e "${YELLOW}Please enter your public key to monitor:${NC}"
+    echo ""
+    read -p "Public Key: " USER_WALLET
+    
+    # Validate input
+    if [ -z "$USER_WALLET" ]; then
+        echo -e "${RED}Error: No wallet address provided!${NC}"
+        exit 1
+    fi
+    
+    # Save to config
+    echo "$USER_WALLET" > "$CONFIG_FILE"
+    echo ""
+    echo -e "${GREEN}✓ Wallet saved! Starting monitor...${NC}"
+    sleep 2
+else
+    # Read wallet from config
+    USER_WALLET=$(cat "$CONFIG_FILE")
+fi
+
+# Header
+clear
+echo -e "${CYAN}╔══════════════════════════════════════════════════════════════════╗${NC}"
+echo -e "${CYAN}║                      NOCKCHAIN WALLET MONITOR                    ║${NC}"
+echo -e "${CYAN}╚══════════════════════════════════════════════════════════════════╝${NC}"
+echo ""
+echo -e "${YELLOW}Checking blockchain...${NC}"
+echo -e "${BLUE}Your wallet:${NC} ${CYAN}${USER_WALLET:0:20}...${USER_WALLET: -20}${NC}"
+echo ""
+
+# Get wallet output and extract signers (FIXED: Added tr -d '\0' to remove null bytes)
+WALLET_OUTPUT=$(/app/wallet/nockchain-wallet --nockchain-socket /app/data/nockchain.sock  list-notes 2>/dev/null | tr -d '\0')
+
+# Extract all wallet addresses from signers field
+WALLETS=$(echo "$WALLET_OUTPUT" | grep -oP '(?<=pks=<\|)[^|]+(?=\|>)' | sort | uniq)
+
+# If no wallets found
+if [ -z "$WALLETS" ]; then
+    echo -e "${RED}No mined blocks found in wallet data.${NC}"
+    echo ""
+    echo -e "${BLUE}Your blocks:${NC} ${RED}0${NC}"
+    echo ""
+    echo -e "${YELLOW}Keep mining! 💪${NC}"
+    exit 0
+fi
+
+# Count total unique wallets
+UNIQUE_COUNT=$(echo "$WALLETS" | wc -l)
+
+echo -e "${GREEN}═══════════════════════════════════════════════════════════════════${NC}"
+echo -e "${GREEN}                    BLOCKCHAIN MINING SUMMARY                       ${NC}"
+echo -e "${GREEN}═══════════════════════════════════════════════════════════════════${NC}"
+echo ""
+echo -e "${BLUE}Total unique miners:${NC} ${YELLOW}$UNIQUE_COUNT${NC}"
+echo ""
+echo -e "${PURPLE}MINER RANKINGS:${NC}"
+echo -e "${PURPLE}───────────────${NC}"
+
+# Process each wallet
+USER_BLOCKS=0
+RANK=1
+
+while IFS= read -r wallet; do
+    # Count occurrences (will be doubled)
+    COUNT=$(echo "$WALLET_OUTPUT" | grep -c "$wallet")
+    # Divide by 2
+    BLOCKS=$((COUNT / 2))
+    
+    # Check if it's user's wallet
+    WALLET_TAG=""
+    if [ "$wallet" = "$USER_WALLET" ]; then
+        USER_BLOCKS=$BLOCKS
+        WALLET_TAG=" ${GREEN}← YOU!${NC}"
+    fi
+    
+    # Display wallet (truncated for readability)
+    WALLET_SHORT="${wallet:0:20}...${wallet: -20}"
+    
+    echo -e "${YELLOW}#$RANK${NC} ${CYAN}$WALLET_SHORT${NC}"
+    echo -e "   ${GREEN}Blocks mined: $BLOCKS${NC}$WALLET_TAG"
+    echo ""
+    
+    RANK=$((RANK + 1))
+done <<< "$WALLETS"
+
+# Summary for user
+echo -e "${GREEN}═══════════════════════════════════════════════════════════════════${NC}"
+echo -e "${GREEN}                        YOUR STANDINGS                              ${NC}"
+echo -e "${GREEN}═══════════════════════════════════════════════════════════════════${NC}"
+echo ""
+
+# Your results
+if [ $USER_BLOCKS -gt 0 ]; then
+    echo -e "${BLUE}Your blocks:${NC} ${GREEN}$USER_BLOCKS 🎉${NC}"
+    YOUR_RANK=$(echo "$WALLETS" | grep -n "^$USER_WALLET$" | cut -d: -f1)
+    echo -e "${BLUE}Your rank:${NC} ${YELLOW}#$YOUR_RANK${NC} out of ${YELLOW}$UNIQUE_COUNT${NC} miners"
+else
+    echo -e "${BLUE}Your blocks:${NC} ${RED}0${NC} ${YELLOW}(Keep mining!)${NC}"
+fi
+
+echo ""
+echo -e "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
+echo -e "Last checked: $(date '+%Y-%m-%d %H:%M:%S')"
+echo ""
+
+# Fun stats
+TOTAL_BLOCKS=$(echo "$WALLETS" | while read w; do echo "$WALLET_OUTPUT" | grep -c "$w"; done | awk '{sum+=$1} END {print sum/2}')
+echo -e "${PURPLE}Network Stats:${NC}"
+echo -e "  Total blocks mined: ${YELLOW}$TOTAL_BLOCKS${NC}"
+echo -e "  Average per miner: ${YELLOW}$(($TOTAL_BLOCKS / $UNIQUE_COUNT))${NC}"
+
+# If user has blocks, celebrate!
+if [ $USER_BLOCKS -gt 0 ]; then
+    echo ""
+    echo -e "${GREEN}🎊 🎊 🎊 CONGRATULATIONS! YOU'RE EARNING NOCK! 🎊 🎊 🎊${NC}"
+fi
+
+echo ""
+
+# Add option to change wallet
+echo -e "${CYAN}───────────────────────────────────────────────────────────────────${NC}"
+echo -e "${BLUE}To monitor a different wallet, delete the config file:${NC}"
+echo -e "${YELLOW}rm $CONFIG_FILE${NC}"
+echo ""

+ 5 - 0
docker-compose.yml

@@ -18,3 +18,8 @@ services:
       - "--bind"
       - "/ip4/0.0.0.0/udp/3006/quic-v1"
       - "--mine"
+    logging:
+      driver: "json-file"
+      options:
+        max-size: "10m"
+        max-file: "3"

+ 3 - 3
entrypoint.sh

@@ -2,9 +2,9 @@
 
 echo "starting nockchain with $@"
 
-export RUST_BACKTRACE=1
-export RUST_LOG=info,nockchain=debug,nockchain_libp2p_io=trace,libp2p=info,libp2p_quic=info
-export MINIMAL_LOG_FORMAT=false
+export RUST_BACKTRACE=${RUST_BACKTRACE:-1}
+export RUST_LOG=${RUST_LOG:-info}
+export MINIMAL_LOG_FORMAT=${MINIMAL_LOG_FORMAT:-false}
 
 rm -f nockchain.sock
 

+ 0 - 680
lib.rs

@@ -1,680 +0,0 @@
-pub mod mining;
-
-use std::error::Error;
-use std::fs;
-use std::path::Path;
-
-use clap::{arg, command, ArgAction, Parser};
-use libp2p::identity::Keypair;
-use libp2p::multiaddr::Multiaddr;
-use libp2p::{allow_block_list, connection_limits, memory_connection_limits, PeerId};
-use nockapp::driver::Operation;
-use nockapp::kernel::boot;
-use nockapp::wire::Wire;
-use nockapp::{one_punch_driver, NockApp, NounExt};
-use nockchain_bitcoin_sync::{bitcoin_watcher_driver, BitcoinRPCConnection, GenesisNodeType};
-use nockchain_libp2p_io::p2p::{
-    MAX_ESTABLISHED_CONNECTIONS, MAX_ESTABLISHED_CONNECTIONS_PER_PEER,
-    MAX_ESTABLISHED_INCOMING_CONNECTIONS, MAX_ESTABLISHED_OUTGOING_CONNECTIONS,
-    MAX_PENDING_INCOMING_CONNECTIONS, MAX_PENDING_OUTGOING_CONNECTIONS,
-};
-use termcolor::{ColorChoice, StandardStream};
-use tokio::net::UnixListener;
-pub mod colors;
-use std::path::PathBuf;
-
-use clap::value_parser;
-use colors::*;
-use nockapp::noun::slab::NounSlab;
-use nockvm::jets::hot::HotEntry;
-use nockvm::noun::{D, T};
-use nockvm_macros::tas;
-use tracing::{debug, info, instrument};
-
-use crate::mining::MiningKeyConfig;
-
-/// Module for handling driver initialization signals
-pub mod driver_init {
-    use nockapp::driver::{make_driver, IODriverFn, PokeResult};
-    use nockapp::noun::slab::NounSlab;
-    use nockapp::wire::{SystemWire, Wire};
-    use nockvm::noun::{D, T};
-    use nockvm_macros::tas;
-    use tokio::sync::oneshot;
-    use tracing::{debug, error, info};
-
-    /// A collection of initialization signals for drivers
-    #[derive(Default)]
-    pub struct DriverInitSignals {
-        /// Sender for the born signal
-        pub born_tx: Option<oneshot::Sender<()>>,
-        /// Receiver for the born signal
-        pub born_rx: Option<oneshot::Receiver<()>>,
-        /// Map of driver names to their initialization signal senders
-        pub driver_signals: std::collections::HashMap<String, oneshot::Receiver<()>>,
-    }
-
-    impl DriverInitSignals {
-        /// Create a new DriverInitSignals instance
-        pub fn new() -> Self {
-            let (born_tx, born_rx) = oneshot::channel();
-            Self {
-                born_tx: Some(born_tx),
-                born_rx: Some(born_rx),
-                driver_signals: std::collections::HashMap::new(),
-            }
-        }
-
-        /// Register a driver with an initialization signal
-        pub fn register_driver(&mut self, name: &str) -> oneshot::Sender<()> {
-            let (tx, rx) = oneshot::channel();
-            self.driver_signals.insert(name.to_string(), rx);
-            tx
-        }
-
-        /// Get the initialization signal sender for a driver
-        pub fn get_signal_sender(&self, name: &str) -> Option<&oneshot::Receiver<()>> {
-            self.driver_signals.get(name)
-        }
-
-        /// Create a task that waits for all registered drivers to initialize
-        pub fn create_born_task(&mut self) -> tokio::task::JoinHandle<()> {
-            let born_tx = self.born_tx.take().expect("Born signal already used");
-            let driver_signals = std::mem::take(&mut self.driver_signals);
-
-            tokio::spawn(async move {
-                // Wait for all registered drivers to initialize concurrently
-                let mut join_set = tokio::task::JoinSet::new();
-                for (name, rx) in driver_signals {
-                    let name = name.clone();
-                    join_set.spawn(async move {
-                        let _ = rx.await;
-                        info!("driver '{}' initialized", name);
-                    });
-                }
-
-                // Wait for all tasks to complete
-                while let Some(result) = join_set.join_next().await {
-                    result.expect("Task panicked");
-                }
-
-                // Send the born poke signal
-                let _ = born_tx.send(());
-                info!("all drivers initialized, born poke sent");
-            })
-        }
-
-        /// Create the born driver that waits for the born signal
-        pub fn create_born_driver(&mut self) -> IODriverFn {
-            let born_rx = self.born_rx.take().expect("born signal already used");
-
-            make_driver(move |handle| {
-                Box::pin(async move {
-                    // Wait for the born signal
-                    let _ = born_rx.await;
-
-                    // Send the born poke
-                    let mut born_slab = NounSlab::new();
-                    let born = T(
-                        &mut born_slab,
-                        &[D(tas!(b"command")), D(tas!(b"born")), D(0)],
-                    );
-                    born_slab.set_root(born);
-                    let wire = SystemWire.to_wire();
-                    let result = handle.poke(wire, born_slab).await?;
-
-                    match result {
-                        PokeResult::Ack => debug!("born poke acknowledged"),
-                        PokeResult::Nack => error!("Born poke nacked"),
-                    }
-
-                    Ok(())
-                })
-            })
-        }
-    }
-}
-
-// TODO: command-line/configure
-/** Path to read current node's identity from */
-pub const IDENTITY_PATH: &str = ".nockchain_identity";
-
-/** Path to read current node's peer ID from */
-pub const PEER_ID_EXTENSION: &str = ".peer_id";
-
-// TODO: command-line/configure
-/** Extension for peer ID files */
-const PEER_ID_FILE_EXTENSION: &str = "peerid";
-
-// Libp2p multiaddrs don't support const construction, so we have to put strings literals and parse them at startup
-/** Backbone nodes for our testnet */
-const TESTNET_BACKBONE_NODES: &[&str] = &[];
-
-// Libp2p multiaddrs don't support const construction, so we have to put strings literals and parse them at startup
-// TODO: feature flag testnet/realnet
-/** Backbone nodes for our realnet */
-#[allow(dead_code)]
-const REALNET_BACKBONE_NODES: &[&str] = &[
-    "/dnsaddr/nockchain-backbone.zorp.io",
-    "/ip4/34.35.75.234/udp/30000/quic-v1",
-    "/ip4/34.176.41.23/udp/30000/quic-v1",
-    "/ip4/34.16.237.144/udp/30000/quic-v1",
-    "/ip4/34.85.34.153/udp/30000/quic-v1",
-    "/ip4/34.95.155.151/udp/30000/quic-v1",
-    "/ip4/34.97.242.48/udp/30000/quic-v1",
-    "/ip4/34.162.206.28/udp/30000/quic-v1",
-    "/ip4/34.174.22.166/udp/30000/quic-v1",
-    "/ip4/34.129.248.106/udp/30000/quic-v1",
-    "/ip4/34.18.98.38/udp/30000/quic-v1"
-];
-
-/** How often we should affirmatively ask other nodes for their heaviest chain */
-const CHAIN_INTERVAL_SECS: u64 = 20;
-
-/// The height of the bitcoin block that we want to sync our genesis block to
-/// Currently, this is the height of an existing block for testing. It will be
-/// switched to a future block for launch.
-const GENESIS_HEIGHT: u64 = 897767;
-
-/// Command line arguments
-#[derive(Parser, Debug, Clone)]
-#[command(name = "nockchain")]
-pub struct NockchainCli {
-    #[command(flatten)]
-    pub nockapp_cli: nockapp::kernel::boot::Cli,
-    #[arg(
-        long,
-        help = "npc socket path",
-        default_value = ".socket/nockchain_npc.sock"
-    )]
-    pub npc_socket: String,
-    #[arg(long, help = "Mine in-kernel", default_value = "false")]
-    pub mine: bool,
-    #[arg(
-        long,
-        help = "Pubkey to mine to (mutually exclusive with --mining-key-adv)"
-    )]
-    pub mining_pubkey: Option<String>,
-    #[arg(
-        long,
-        help = "Advanced mining key configuration (mutually exclusive with --mining-pubkey). Format: share,m:key1,key2,key3",
-        value_parser = value_parser!(MiningKeyConfig),
-        num_args = 1..,
-        value_delimiter = ',',
-    )]
-    pub mining_key_adv: Option<Vec<MiningKeyConfig>>,
-    #[arg(long, help = "Watch for genesis block", default_value = "false")]
-    pub genesis_watcher: bool,
-    #[arg(long, help = "Mine genesis block", default_value = "false")]
-    pub genesis_leader: bool,
-    #[arg(long, help = "use fake genesis block", default_value = "false")]
-    pub fakenet: bool,
-    #[arg(long, help = "Genesis block message", default_value = "Hail Zorp")]
-    pub genesis_message: String,
-    #[arg(
-        long,
-        help = "URL for Bitcoin Core RPC",
-        default_value = "http://100.98.183.39:8332"
-    )]
-    pub btc_node_url: String,
-    #[arg(long, help = "Username for Bitcoin Core RPC")]
-    pub btc_username: Option<String>,
-    #[arg(long, help = "Password for Bitcoin Core RPC")]
-    pub btc_password: Option<String>,
-    #[arg(long, help = "Auth cookie path for Bitcoin Core RPC")]
-    pub btc_auth_cookie: Option<String>,
-    #[arg(long, short, help = "Initial peer", action = ArgAction::Append)]
-    pub peer: Vec<String>,
-    #[arg(long, help = "Allowed peer IDs file")]
-    pub allowed_peers_path: Option<String>,
-    #[arg(long, help = "Don't dial default peers")]
-    pub no_default_peers: bool,
-    #[arg(long, help = "Bind address", action = ArgAction::Append)]
-    pub bind: Vec<String>,
-    #[arg(
-        long,
-        help = "Generate a new peer ID, discarding the existing one",
-        default_value = "false"
-    )]
-    pub new_peer_id: bool,
-    #[arg(long, help = "Maximum established incoming connections")]
-    pub max_established_incoming: Option<u32>,
-    #[arg(long, help = "Maximum established outgoing connections")]
-    pub max_established_outgoing: Option<u32>,
-    #[arg(long, help = "Maximum pending incoming connections")]
-    pub max_pending_incoming: Option<u32>,
-    #[arg(long, help = "Maximum pending outgoing connections")]
-    pub max_pending_outgoing: Option<u32>,
-    #[arg(long, help = "Maximum established connections")]
-    pub max_established: Option<u32>,
-    #[arg(long, help = "Maximum established connections per peer")]
-    pub max_established_per_peer: Option<u32>,
-    #[arg(long, help = "Maximum system memory percentage for connection limits")]
-    pub max_system_memory_fraction: Option<f64>,
-    #[arg(long, help = "Maximum process memory for connection limits (bytes)")]
-    pub max_system_memory_bytes: Option<usize>,
-}
-
-impl NockchainCli {
-    pub fn validate(&self) -> Result<(), String> {
-        if self.mine && !(self.mining_pubkey.is_some() || self.mining_key_adv.is_some()) {
-            return Err(
-                "Cannot specify mine without either mining_pubkey or mining_key_adv".to_string(),
-            );
-        }
-
-        if self.mining_pubkey.is_some() && self.mining_key_adv.is_some() {
-            return Err(
-                "Cannot specify both mining_pubkey and mining_key_adv at the same time".to_string(),
-            );
-        }
-
-        if self.genesis_leader && self.genesis_watcher {
-            return Err(
-                "Cannot specify both genesis_leader and genesis_watcher at the same time"
-                    .to_string(),
-            );
-        }
-
-        if !self.fakenet && (self.genesis_watcher || self.genesis_leader) {
-            if self.btc_node_url.is_empty() {
-                return Err(
-                    "Must specify --btc-node-url when using genesis_watcher or genesis_leader"
-                        .to_string(),
-                );
-            }
-            if self.btc_auth_cookie.is_none() {
-                if self.btc_username.is_none() && self.btc_password.is_none() {
-                    return Err("Must specify either --btc-username or --btc-password when using genesis_watcher or genesis_leader on livenet".to_string());
-                }
-            }
-        }
-
-        Ok(())
-    }
-
-    /// Helper function to create a BitcoinRPCConnection from CLI arguments
-    fn create_bitcoin_connection(&self) -> BitcoinRPCConnection {
-        let url = self.btc_node_url.clone();
-        let height = GENESIS_HEIGHT;
-        let auth = if let Some(username) = self.btc_username.clone() {
-            let password = self.btc_password.clone().unwrap_or_else(|| {
-                panic!(
-                    "Panicked at {}:{} (git sha: {:?})",
-                    file!(),
-                    line!(),
-                    option_env!("GIT_SHA")
-                )
-            });
-            bitcoincore_rpc::Auth::UserPass(username, password)
-        } else {
-            let cookie_path_str = self.btc_auth_cookie.clone().unwrap_or_else(|| {
-                panic!(
-                    "Panicked at {}:{} (git sha: {:?})",
-                    file!(),
-                    line!(),
-                    option_env!("GIT_SHA")
-                )
-            });
-            let cookie_path = PathBuf::from(cookie_path_str);
-            bitcoincore_rpc::Auth::CookieFile(cookie_path)
-        };
-        BitcoinRPCConnection::new(url, auth, height)
-    }
-}
-
-/// # Load a keypair from a file or create a new one if the file doesn't exist
-///
-/// This function attempts to read a keypair from a specified file. If the file exists, it reads the keypair from the file.
-/// If the file does not exist, it generates a new keypair, writes it to the file, and returns it.
-///
-/// # Arguments
-/// * `keypair_path` - A reference to a Path object representing the file path where the keypair should be stored
-/// * `force_new` - If true, generate a new keypair even if one already exists
-///
-/// # Returns
-/// A Result containing the Keypair or an error if any operation fails
-pub fn gen_keypair(keypair_path: &Path) -> Result<Keypair, Box<dyn Error>> {
-    let new_keypair = libp2p::identity::Keypair::generate_ed25519();
-    let new_keypair_bytes = new_keypair.to_protobuf_encoding()?;
-    std::fs::write(keypair_path, new_keypair_bytes)?;
-    let peer_id = new_keypair.public().to_peer_id();
-    // write the peer_id encoded as base58 to a file
-    std::fs::write(
-        keypair_path.with_extension(PEER_ID_FILE_EXTENSION),
-        peer_id.to_base58(),
-    )?;
-    info!("Generated new identity as peer {peer_id}");
-    Ok(new_keypair)
-}
-
-fn load_keypair(keypair_path: &Path, force_new: bool) -> Result<Keypair, Box<dyn Error>> {
-    if keypair_path.try_exists()? && !force_new {
-        let keypair_bytes = std::fs::read(keypair_path)?;
-        let keypair = libp2p::identity::Keypair::from_protobuf_encoding(&keypair_bytes[..])?;
-        let peer_id = keypair.public().to_peer_id();
-        info!("Loaded identity as peer {peer_id}");
-        Ok(keypair)
-    } else {
-        if force_new && keypair_path.try_exists()? {
-            info!("Discarding existing peer ID and generating a new one");
-            std::fs::remove_file(keypair_path)?;
-        }
-        gen_keypair(keypair_path)
-    }
-}
-
-#[instrument(skip(kernel_jam, hot_state))]
-pub async fn init_with_kernel(
-    cli: Option<NockchainCli>,
-    kernel_jam: &[u8],
-    hot_state: &[HotEntry],
-) -> Result<NockApp, Box<dyn Error>> {
-    welcome();
-
-    if let Some(cli) = &cli {
-        cli.validate()?;
-    }
-
-    let mut nockapp = boot::setup(
-        kernel_jam,
-        cli.as_ref().map(|c| c.nockapp_cli.clone()),
-        hot_state,
-        "nockchain",
-        None,
-    )
-    .await?;
-
-    let keypair = {
-        let keypair_path = Path::new(IDENTITY_PATH);
-        load_keypair(
-            keypair_path,
-            cli.as_ref().map(|c| c.new_peer_id).unwrap_or(false),
-        )?
-    };
-    eprintln!(
-        "allowed_peers_path: {:?}",
-        cli.as_ref().unwrap().allowed_peers_path
-    );
-    let allowed = cli.as_ref().and_then(|c| {
-        c.allowed_peers_path.as_ref().map(|path| {
-            let contents = fs::read_to_string(path).expect("failed to read allowed peers file: {}");
-            let peer_ids: Vec<PeerId> = contents
-                .lines()
-                .map(|line| {
-                    let peer_id_bytes = bs58::decode(line)
-                        .into_vec()
-                        .expect("failed to decode peer ID bytes from base58");
-                    PeerId::from_bytes(&peer_id_bytes).expect("failed to decode peer ID from bytes")
-                })
-                .collect();
-            let mut allow_behavior =
-                allow_block_list::Behaviour::<allow_block_list::AllowedPeers>::default();
-            for peer_id in peer_ids {
-                allow_behavior.allow_peer(peer_id);
-            }
-            allow_behavior
-        })
-    });
-
-    let bind_multiaddrs = cli
-        .as_ref()
-        .map_or(vec!["/ip4/0.0.0.0/udp/0/quic-v1".parse()?], |c| {
-            c.bind
-                .clone()
-                .into_iter()
-                .map(|addr_str| addr_str.parse().expect("could not parse bind multiaddr"))
-                .collect()
-        });
-
-    let limits = connection_limits::ConnectionLimits::default()
-        .with_max_established_incoming(
-            cli.as_ref()
-                .and_then(|c| c.max_established_incoming)
-                .and(Some(MAX_ESTABLISHED_INCOMING_CONNECTIONS)),
-        )
-        .with_max_established_outgoing(
-            cli.as_ref()
-                .and_then(|c| c.max_established_outgoing)
-                .and(Some(MAX_ESTABLISHED_OUTGOING_CONNECTIONS)),
-        )
-        .with_max_pending_incoming(
-            cli.as_ref()
-                .and_then(|c| c.max_pending_incoming)
-                .and(Some(MAX_PENDING_INCOMING_CONNECTIONS)),
-        )
-        .with_max_pending_outgoing(
-            cli.as_ref()
-                .and_then(|c| c.max_pending_outgoing)
-                .and(Some(MAX_PENDING_OUTGOING_CONNECTIONS)),
-        )
-        .with_max_established(
-            cli.as_ref()
-                .and_then(|c| c.max_established)
-                .and(Some(MAX_ESTABLISHED_CONNECTIONS)),
-        )
-        .with_max_established_per_peer(
-            cli.as_ref()
-                .and_then(|c| c.max_established_per_peer)
-                .and(Some(MAX_ESTABLISHED_CONNECTIONS_PER_PEER)),
-        );
-    let memory_limits = cli.as_ref().and_then(|c| {
-        if c.max_system_memory_bytes.is_some() && c.max_system_memory_fraction.is_some() { panic!( "Must provide neither or one of --max-system-memory_bytes or --max-system-memory_percentage" )};
-        if let Some(max_bytes) = c.max_system_memory_bytes {
-            Some(memory_connection_limits::Behaviour::with_max_bytes(max_bytes))
-        } else { c.max_system_memory_fraction.map(memory_connection_limits::Behaviour::with_max_percentage) }
-    });
-
-    let default_backbone_peers = if cli.as_ref().map(|c| c.fakenet).unwrap_or(false) {
-        TESTNET_BACKBONE_NODES
-    } else {
-        REALNET_BACKBONE_NODES
-    };
-
-    let backbone_peers = default_backbone_peers
-        .iter()
-        .map(|multiaddr_str| {
-            multiaddr_str
-                .parse()
-                .expect("could not parse multiaddr from built-in string")
-        })
-        .collect();
-
-    // Set up initial peer addresses to connect to
-    let mut peer_multiaddrs: Vec<Multiaddr> = if cli.as_ref().is_some_and(|c| c.no_default_peers) {
-        Vec::new()
-    } else {
-        backbone_peers
-    };
-
-    if let Some(c) = cli.as_ref() {
-        let v: Vec<Multiaddr> = c
-            .peer
-            .clone()
-            .into_iter()
-            .map(|multiaddr_str| {
-                multiaddr_str
-                    .parse()
-                    .expect("could not parse multiaddr from string")
-            })
-            .collect();
-        peer_multiaddrs.extend(v);
-    }
-
-    debug!("peer_multiaddrs: {:?}", peer_multiaddrs);
-
-    let equix_builder = equix::EquiXBuilder::new();
-
-    // Create driver initialization signals. the idea here is that we want to wait for
-    // drivers that emit init pokes to complete before we send the born poke.
-    let mut driver_signals = driver_init::DriverInitSignals::new();
-
-    // Register drivers that need initialization signals
-    let mining_init_tx = driver_signals.register_driver("mining");
-    let libp2p_init_tx = driver_signals.register_driver("libp2p");
-    let watcher_init_tx = driver_signals.register_driver("bitcoin_watcher");
-
-    // Create the born task that waits for all drivers to initialize
-    let _born_task = driver_signals.create_born_task();
-
-    if cli.as_ref().map(|c| c.fakenet).unwrap_or(false) {
-        let message = cli
-            .as_ref()
-            .map(|c| c.genesis_message.clone())
-            .unwrap_or("".to_string());
-        let node_type = if cli.as_ref().map(|c| c.genesis_leader).unwrap_or(false) {
-            GenesisNodeType::Leader
-        } else {
-            GenesisNodeType::Watcher
-        };
-        let watcher_driver =
-            bitcoin_watcher_driver(None, node_type, message, Some(watcher_init_tx));
-        nockapp.add_io_driver(watcher_driver).await;
-    } else if cli
-        .as_ref()
-        .map(|c| c.genesis_watcher || c.genesis_leader)
-        .unwrap_or(false)
-    {
-        let message = cli
-            .as_ref()
-            .map(|c| c.genesis_message.clone())
-            .unwrap_or("".to_string());
-        let connection = cli.as_ref().unwrap().create_bitcoin_connection();
-        let node_type = if cli.as_ref().map(|c| c.genesis_leader).unwrap_or(false) {
-            GenesisNodeType::Leader
-        } else {
-            GenesisNodeType::Watcher
-        };
-        let watcher_driver =
-            bitcoin_watcher_driver(Some(connection), node_type, message, Some(watcher_init_tx));
-        nockapp.add_io_driver(watcher_driver).await;
-    } else {
-        // Realnet with no BTC node
-        let mut poke_slab = NounSlab::new();
-        let poke_noun = T(
-            &mut poke_slab,
-            &[D(tas!(b"command")), D(tas!(b"btc-data")), D(0)],
-        );
-        poke_slab.set_root(poke_noun);
-        nockapp
-            .poke(nockapp::wire::SystemWire.to_wire(), poke_slab)
-            .await
-            .expect("Failed to poke for no BTC hash");
-    }
-
-    let mining_config = cli.as_ref().and_then(|c| {
-        if let Some(pubkey) = &c.mining_pubkey {
-            Some(vec![MiningKeyConfig {
-                share: 1,
-                m: 1,
-                keys: vec![pubkey.clone()],
-            }])
-        } else if let Some(mining_key_adv) = &c.mining_key_adv {
-            Some(mining_key_adv.clone())
-        } else {
-            None
-        }
-    });
-
-    let mine = cli.as_ref().map_or(false, |c| c.mine);
-
-    let mining_driver =
-        crate::mining::create_mining_driver(mining_config, mine, Some(mining_init_tx));
-    nockapp.add_io_driver(mining_driver).await;
-
-    let libp2p_driver = nockchain_libp2p_io::nc::make_libp2p_driver(
-        keypair,
-        bind_multiaddrs,
-        allowed,
-        limits,
-        memory_limits,
-        &peer_multiaddrs,
-        equix_builder,
-        Some(libp2p_init_tx),
-    );
-    nockapp.add_io_driver(libp2p_driver).await;
-
-    // Create the born driver that waits for the born signal
-    let born_driver = driver_signals.create_born_driver();
-
-    // Add the born driver to the nockapp
-    nockapp.add_io_driver(born_driver).await;
-
-    // set up socket
-    let socket_path = Path::new(
-        &cli.as_ref()
-            .unwrap_or_else(|| {
-                panic!(
-                    "Panicked at {}:{} (git sha: {:?})",
-                    file!(),
-                    line!(),
-                    option_env!("GIT_SHA")
-                )
-            })
-            .npc_socket,
-    );
-    nockapp.npc_socket_path = Some(socket_path.to_path_buf());
-
-    if let Some(parent) = socket_path.parent() {
-        fs::create_dir_all(parent)?;
-    }
-    let listener = UnixListener::bind(socket_path)?;
-
-    nockapp
-        .add_io_driver(nockapp::npc_listener_driver(listener))
-        .await;
-
-    // set up timer
-    let mut timer_slab = NounSlab::new();
-    let timer_noun = T(
-        &mut timer_slab,
-        &[D(tas!(b"command")), D(tas!(b"timer")), D(0)],
-    );
-    timer_slab.set_root(timer_noun);
-    nockapp
-        .add_io_driver(nockapp::timer_driver(CHAIN_INTERVAL_SECS, timer_slab))
-        .await;
-
-    nockapp.add_io_driver(nockapp::exit_driver()).await;
-
-    Ok(nockapp)
-}
-
-fn welcome() {
-    let mut stdout = StandardStream::stdout(ColorChoice::Auto);
-
-    let banner = "
-    _   _            _        _           _
-   | \\ | | ___   ___| | _____| |__   __ _(_)_ __
-   |  \\| |/ _ \\ / __| |/ / __| '_ \\ / _` | | '_ \\
-   | |\\  | (_) | (__|   < (__| | | | (_| | | | | |
-   |_| \\_|\\___/ \\___|_|\\_\\___|_| |_|\\__,_|_|_| |_|
-   ";
-
-    print_banner(&mut stdout, banner);
-
-    let info = [
-        ("Build label", env!("BUILD_EMBED_LABEL")),
-        ("Build host", env!("BUILD_HOST")),
-        ("Build user", env!("BUILD_USER")),
-        ("Build timestamp", env!("BUILD_TIMESTAMP")),
-        ("Build date", env!("FORMATTED_DATE")),
-        // ("Git commit", env!("BAZEL_GIT_COMMIT")),
-        // ("Build timestamp", env!("VERGEN_BUILD_TIMESTAMP")),
-        // ("Cargo debug", env!("VERGEN_CARGO_DEBUG")),
-        // ("Cargo features", env!("VERGEN_CARGO_FEATURES")),
-        // ("Cargo opt level", env!("VERGEN_CARGO_OPT_LEVEL")),
-        // ("Cargo target", env!("VERGEN_CARGO_TARGET_TRIPLE")),
-        // ("Git branch", env!("VERGEN_GIT_BRANCH")),
-        // ("Git commit date", env!("VERGEN_GIT_COMMIT_DATE")),
-        // ("Git commit author", env!("VERGEN_GIT_COMMIT_AUTHOR_NAME")),
-        // ("Git commit message", env!("VERGEN_GIT_COMMIT_MESSAGE")),
-        // ("Git commit timestamp", env!("VERGEN_GIT_COMMIT_TIMESTAMP")),
-        // ("Git commit SHA", env!("VERGEN_GIT_SHA")),
-        // ("Rustc channel", env!("VERGEN_RUSTC_CHANNEL")),
-        // ("Rustc host", env!("VERGEN_RUSTC_HOST_TRIPLE")),
-        // ("Rustc LLVM version", env!("VERGEN_RUSTC_LLVM_VERSION")),
-    ];
-
-    print_version_info(&mut stdout, &info);
-}