From 00ce004ae54a86b891c2a21350f2a75c7f31490d Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Tue, 21 Jun 2011 22:53:57 +0100 Subject: [PATCH] Skeletor of integrating em-bitcoin with sharpcoin. The server process actually runs now(!) - although it does nothing useful. --- lib/sharp-coin.rb | 5 +- lib/sharp-coin/config.rb | 14 +++++- lib/sharp-coin/db.rb | 13 +++-- lib/sharp-coin/interface.rb | 1 + lib/sharp-coin/interface/bitcoin.rb | 48 ++++++++++++++++++- .../interface/bitcoin/client_actor.rb | 18 +++++++ .../interface/bitcoin/server_actor.rb | 18 +++++++ lib/sharp-coin/server.rb | 21 ++++---- 8 files changed, 115 insertions(+), 23 deletions(-) create mode 100644 lib/sharp-coin/interface/bitcoin/client_actor.rb create mode 100644 lib/sharp-coin/interface/bitcoin/server_actor.rb diff --git a/lib/sharp-coin.rb b/lib/sharp-coin.rb index 9087a90..c7f29de 100644 --- a/lib/sharp-coin.rb +++ b/lib/sharp-coin.rb @@ -1,5 +1,2 @@ -require 'sharp-coin/config' -require 'sharp-coin/db' -require 'sharp-coin/logging' require 'sharp-coin/server' -require 'sharp-coin/interface' + diff --git a/lib/sharp-coin/config.rb b/lib/sharp-coin/config.rb index a4916f5..e00d8eb 100644 --- a/lib/sharp-coin/config.rb +++ b/lib/sharp-coin/config.rb @@ -45,8 +45,20 @@ module SharpCoin [telnet_host, telnet_port] end + def bitcoin_host + "localhost" + end + + def bitcoin_port + 8333 + end + + def bitcoin_bind + [bitcoin_host, bitcoin_port] + end + def db_settings - { :adapter => 'sqlite', :database => 'sharp-coin.sqlite' } + { :adapter => 'sqlite3', :database => 'sharp-coin.sqlite' } end def db_automigrate? diff --git a/lib/sharp-coin/db.rb b/lib/sharp-coin/db.rb index 30f9482..ffe352d 100644 --- a/lib/sharp-coin/db.rb +++ b/lib/sharp-coin/db.rb @@ -1,3 +1,6 @@ +require 'sharp-coin/logging' +require 'sharp-coin/config' + begin require 'active_record' rescue LoadError => err @@ -5,23 +8,23 @@ rescue LoadError => err retry end +require 'sqlite3' + module SharpCoin module DB - include Logging class << self - def setup! + def setup!(logger, config = SharpCoin::Config::db_settings) ActiveRecord::Base.logger = logger ActiveRecord::Base.include_root_in_json = false - ActiveRecord::Base.establish_connection(Config::db_settings) + ActiveRecord::Base.establish_connection(config) if Config::db_automigrate? - log(:info, "Performing automigration") + logger.info("Performing automigration") ActiveRecord::Migration.verbose = false ActiveRecord::Migrator.migrate(File.join(File.dirname(__FILE__), 'db', 'migrations')) end -tup! end diff --git a/lib/sharp-coin/interface.rb b/lib/sharp-coin/interface.rb index 914985b..250c9b2 100644 --- a/lib/sharp-coin/interface.rb +++ b/lib/sharp-coin/interface.rb @@ -1,3 +1,4 @@ +require 'sharp-coin/interface/bitcoin' require 'sharp-coin/interface/json-rpc' require 'sharp-coin/interface/rest' require 'sharp-coin/interface/telnet' diff --git a/lib/sharp-coin/interface/bitcoin.rb b/lib/sharp-coin/interface/bitcoin.rb index be89550..5601de7 100644 --- a/lib/sharp-coin/interface/bitcoin.rb +++ b/lib/sharp-coin/interface/bitcoin.rb @@ -1,9 +1,53 @@ +require 'em-bitcoin' + +require 'sharp-coin/interface/bitcoin/client_actor' +require 'sharp-coin/interface/bitcoin/server_actor' + module SharpCoin module Interface - # Handle communications with other BitCoin peers. We rely on - # EM::P::BitcoinPeer for much of the heavy lifting. + + # This is a connection pool for a BitCoin node. + # Responsibilities are accepting incoming connections and making outgoing + # connections to keep up to date with the block chain and propagate user + # transactions. + # # @author Nick Thomas class Bitcoin + class Connection < Struct.new(:sig, :actor) + end + + attr_reader :em, :config, :nonce, :server, :connections + + def self.run(*args) + s = new(*args) + s.run + s + end + + # @param[Module] em EventMachine module + # @param[SharpCoin::Config] configuration settings + def initialize(em, config) + @em = em + @config = config + @nonce = rand(2**32) + @clients = [] + end + + def run + actor = ServerActor.new(self, config) + sig = em.start_server( + config.bitcoin_host, config.bitcoin_port, EM::P::BitcoinServer, + lambda { ServerActor.new(self, config) } + ) + @server = Connection.new(sig, actor) + end + + def stop + em.stop_server(@server.sig) + @connections.each {|client| em.close_connection(client.sig) } + end + end end + end diff --git a/lib/sharp-coin/interface/bitcoin/client_actor.rb b/lib/sharp-coin/interface/bitcoin/client_actor.rb new file mode 100644 index 0000000..db801cb --- /dev/null +++ b/lib/sharp-coin/interface/bitcoin/client_actor.rb @@ -0,0 +1,18 @@ +module SharpCoin ; module Interface ; class Bitcoin + + # This actor mediates between SharpCoin & other bitcoin nodes when SharpCoin + # is acting as a client. + # + # @author Nick Thomas + class ClientActor + attr_reader :node, :config + + # @param[SharpCoin::BTC::Node] node this actor is working for + # @param[SharpCoin::Config] config object + def initialize(node, config) + end + + end + +end ; end ; end + diff --git a/lib/sharp-coin/interface/bitcoin/server_actor.rb b/lib/sharp-coin/interface/bitcoin/server_actor.rb new file mode 100644 index 0000000..90827fd --- /dev/null +++ b/lib/sharp-coin/interface/bitcoin/server_actor.rb @@ -0,0 +1,18 @@ +module SharpCoin ; module Interface ; class Bitcoin + + # This actor mediates between SharpCoin & other bitcoin nodes when SharpCoin + # is acting as a server. + # + # @author Nick Thomas + class ServerActor + attr_reader :node, :config + + # @param[SharpCoin::BTC::Node] node this actor is working for + # @param[SharpCoin::Config] config object + def initialize(node, config) + end + + end + +end ; end ; end + diff --git a/lib/sharp-coin/server.rb b/lib/sharp-coin/server.rb index fba5310..3fe24fe 100644 --- a/lib/sharp-coin/server.rb +++ b/lib/sharp-coin/server.rb @@ -1,8 +1,11 @@ require 'eventmachine' require 'thin' +require 'sharp-coin/logging' +require 'sharp-coin/config' require 'sharp-coin/db' require 'sharp-coin/interface' + module SharpCoin # Beating heart of the SharpCoin application. Sets up all the components # according to the config, handles all the events as needed. @@ -14,9 +17,9 @@ module SharpCoin # of SharpCoin to produce a working application. # @param[ def initialize - DB::setup! + DB::setup!(logger) end - + # Start the various services off. This should generally be called inside an # EM::run { ... } block def run @@ -30,12 +33,7 @@ module SharpCoin Interface::Telnet ) - @bitcoin_server = EM::start_server( - Config::bitcoin_server_host, - Config::bitcoin_server_port, - EM::P::BitcoinServer, - Config - ) + @bitcoin_node = Interface::Bitcoin.run(EM, Config) end # @return[Boolean] Is this server instance currently running? @@ -45,10 +43,11 @@ module SharpCoin # Stop the various services. def stop - @bitcoin_server.stop - @http_server.stop - @telnet_server.stop + @bitcoin_node.stop + EM::stop_server(@http_server) + EM::stop_server(@telnet_server) @running = false + EM::stop end end