Allow lazy actor initialization, add receive_packet, check packet network
This commit is contained in:
@@ -122,23 +122,8 @@ module EventMachine
|
||||
begin
|
||||
packet = BTC::Message.read(@data)
|
||||
used = @data.slice!(0, packet.num_bytes) # Remove data from buf
|
||||
log(:info, "Read #{packet.cmd_sym} packet (#{used.length}b)")
|
||||
log(:debug, used.inspect)
|
||||
log(:debug, packet.inspect)
|
||||
if packet.cmd_sym
|
||||
m = "receive_#{packet.cmd_sym}"
|
||||
if self.respond_to?(m)
|
||||
log(:info, "Received #{packet.cmd_sym}")
|
||||
send(m, packet)
|
||||
else
|
||||
raise NotImplementedError.new("#{m} not implemented")
|
||||
end
|
||||
else
|
||||
log(:warn, "Received packet with no command, discarding it")
|
||||
end
|
||||
rescue IOError # Not enough data
|
||||
finished = true
|
||||
rescue EOFError
|
||||
receive_packet(packet)
|
||||
rescue IOError,EOFError # Not enough data
|
||||
finished = true
|
||||
end
|
||||
end
|
||||
@@ -146,6 +131,34 @@ module EventMachine
|
||||
log(:debug, @data.inspect) if @data.length > 0
|
||||
end
|
||||
|
||||
|
||||
# Checks the passed-in packet for validity and dispatches it if valid
|
||||
# @param[BTC::Message] packet Received packet
|
||||
def receive_packet(packet)
|
||||
log(:info, "Received #{packet.cmd_sym} packet (#{packet.num_bytes}b)")
|
||||
log(:debug, packet.inspect)
|
||||
|
||||
if packet.network_name != actor.network_name
|
||||
log(
|
||||
:info, "Received packet from incorrect network: " +
|
||||
"#{packet.network_name || packet.magic}, discarding"
|
||||
)
|
||||
return nil
|
||||
end
|
||||
|
||||
if packet.cmd_sym
|
||||
m = "receive_#{packet.cmd_sym}"
|
||||
if self.respond_to?(m)
|
||||
log(:info, "Received #{packet.cmd_sym}")
|
||||
send(m, packet)
|
||||
else
|
||||
raise NotImplementedError.new("#{m} not implemented")
|
||||
end
|
||||
else
|
||||
log(:info, "Received packet with no command, discarding it")
|
||||
end
|
||||
end
|
||||
|
||||
# Checks whether we can communicate sensibly with a peer of a particular
|
||||
# version. At the moment, we're fairly liberal about who we try to talk to
|
||||
# @param[Fixnum] their_version Version of the peer under question
|
||||
@@ -188,9 +201,11 @@ module EventMachine
|
||||
class BitcoinClient < EM::Connection
|
||||
include BitcoinPeer
|
||||
|
||||
# @param[Object] actor See the BitcoinPeer#valid_actor?
|
||||
# @param[Object] actor See the BitcoinPeer#valid_actor? method. If this is
|
||||
# a proc, we execute it and use the return value as the actor.
|
||||
def initialize(actor)
|
||||
@actor = actor
|
||||
@actor = @actor.call if actor.is_a?(Proc)
|
||||
result, msg = valid_actor?
|
||||
raise ArgumentError.new("Invalid actor: #{msg}") unless result
|
||||
|
||||
@@ -223,7 +238,7 @@ module EventMachine
|
||||
@ready == :version_sent
|
||||
|
||||
if can_talk_version?(p.payload.version)
|
||||
log(:info, "Valid peer, version is #{p.payload.version}")
|
||||
log(:info, "Notifying actor of ready peer (v.#{p.payload.version})")
|
||||
send_verack
|
||||
@ready = true
|
||||
actor.ready!
|
||||
@@ -248,9 +263,11 @@ module EventMachine
|
||||
my_netaddr.port
|
||||
end
|
||||
|
||||
# @param[Object] actor See the BitcoinPeer#valid_actor? method
|
||||
# @param[Object] actor See the BitcoinPeer#valid_actor? method. If this is
|
||||
# a proc, we execute it and use the return value as the actor.
|
||||
def initialize(actor)
|
||||
@actor = actor
|
||||
@actor = @actor.call if actor.is_a?(Proc)
|
||||
result, msg = valid_actor?
|
||||
raise ArgumentError.new("Invalid actor: #{msg}") unless result
|
||||
|
||||
@@ -279,6 +296,7 @@ module EventMachine
|
||||
def receive_verack(p)
|
||||
raise PE.new("Received verack inappropriately") unless
|
||||
@ready == :version_sent
|
||||
log(:info, "Notifying actor of ready peer (v.#{p.payload.version})")
|
||||
@ready = true
|
||||
actor.ready!
|
||||
end
|
||||
|
Reference in New Issue
Block a user