#!/usr/bin/env ruby $:.unshift( File.expand_path("../../lib", __FILE__) ) require 'bitcoin' require 'optparse' require 'fileutils' Bitcoin.require_dependency :eventmachine Bitcoin.require_dependency :json defaults = Bitcoin::Network::Node::DEFAULT_CONFIG options = Bitcoin::Config.load(defaults, :blockchain) optparse = OptionParser.new do |opts| opts.banner = "Usage: bitcoin_node [options]" opts.separator("\nAvailable options:\n") opts.on("-c", "--config FILE", "Config file (default: #{Bitcoin::Config::CONFIG_PATHS})") do |file| options = Bitcoin::Config.load_file(options, file, :blockchain) end opts.on("-n", "--network [NETWORK]", "User Network (default: #{options[:network]})") do |network| options[:network] = network end opts.on("--command [HOST:PORT]", "Command socket (default: #{options[:command].join(':')})") do |command| options[:command] = command.split(":") end opts.on("-l", "--listen [HOST:PORT]", "Listen address/port (default: #{options[:listen].join(':')})") do |listen| options[:listen] = listen.split(":") end opts.on("--connect [HOST:PORT]", "Hosts to connect to (default: #{options[:connect].map{|c|c.join(':')}.join(',')})") do |connect| connect.split(",").each do |host| options[:connect] << host.split(":") end end opts.on("-a", "--announce", "Announce our own address to the network, so we will get incoming connections.") do options[:announce] = true end opts.on("--external-port PORT", "Specify external port that can be used to reach this node (uses local port otherwise).") do |port| options[:external_port] = port.to_i end opts.on("-s", "--storage [BACKEND::CONFIG]", "Use storage backend (default: #{options[:storage]})") do |storage| options[:storage] = storage end opts.on("--skip-validation", "Skip validation of blocks and transactions") do options[:skip_validation] = true end opts.on("--check-blocks COUNT", "Check consistency of COUNT latest blocks; -1 for all (default: 1000)") do |check| options[:check_blocks] = check.to_i end opts.on("--ho", "--headers-only", "Download only block headers") do options[:headers_only] = true end opts.on("-d", "--dns", "Use DNS seeds (default)") do options[:dns] = true end opts.on("--nd", "--no-dns", "Don't use DNS seeds") do options[:dns] = false end opts.on("--epoll", "Enable epoll support") do options[:epoll] = true end opts.on("--epoll-limit [NUM]", "Increase socket descriptor limit to NUM") do |num| options[:epoll_limit] = num.to_i end opts.on("--epoll-user [NAME]", "Set effective user after increasing socket descriptor limit") do |user| options[:epoll_user] = user end opts.on("--mco", "--max-connections-out COUNT", "Maximum number of outgoing connections (default: #{options[:max][:connections_out]})") do |count| options[:max][:connections_out] = count.to_i end opts.on("--mci", "--max-connections-in COUNT", "Maximum number of incoming connections (default: #{options[:max][:connections_in]})") do |count| options[:max][:connections_in] = count.to_i end [:addr, :queue, :inv, :unconfirmed].each do |name| opts.on("--m#{name.to_s[0]}", "--max-#{name} [COUNT]", "Max #{name} (default: #{options[:max][name]})") do |count| options[:max][name] = count.to_i end end [:queue, :inv_queue, :blocks, :addrs, :connect].each do |name| opts.on("--i#{name.to_s[0]}", "--interval-#{name} [SECONDS]", "Interval for #{name} worker (default: #{options[:intervals][name]})") do |sec| options[:intervals][name] = sec.to_i end end [:network, :storage].each do |name| opts.on("--l#{name.to_s[0]}", "--log-#{name} [LEVEL]", "Log level for #{name} (default: #{options[:log][name]})") do |level| options[:log][name] = level.to_sym end end opts.on("--import DIR", "Import blk*.dat files from DIR") do |dir| options[:import] = dir end opts.on("-v", "--verbose", "Set all loggers to debug") do options[:log].each_key {|k| options[:log][k] = :debug } end opts.on("-q", "--quiet", "Set all loggers to warn") do options[:log].each_key {|k| options[:log][k] = :warn } end opts.on( '-h', '--help', 'Display this screen' ) do puts opts; exit end end optparse.parse! Bitcoin.network = options[:network] FileUtils.mkdir_p File.join(ENV['HOME'], ".bitcoin-ruby/#{Bitcoin.network_name}") if ARGV.any? system(File.join(File.dirname(__FILE__), "bitcoin_node_cli"), *ARGV) else node = Bitcoin::Network::Node.new(options) node.run end