devp2p 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +22 -0
  4. data/lib/devp2p.rb +57 -0
  5. data/lib/devp2p/app_helper.rb +85 -0
  6. data/lib/devp2p/base_app.rb +80 -0
  7. data/lib/devp2p/base_protocol.rb +136 -0
  8. data/lib/devp2p/base_service.rb +55 -0
  9. data/lib/devp2p/command.rb +82 -0
  10. data/lib/devp2p/configurable.rb +32 -0
  11. data/lib/devp2p/connection_monitor.rb +77 -0
  12. data/lib/devp2p/control.rb +32 -0
  13. data/lib/devp2p/crypto.rb +73 -0
  14. data/lib/devp2p/crypto/ecc_x.rb +133 -0
  15. data/lib/devp2p/crypto/ecies.rb +134 -0
  16. data/lib/devp2p/discovery.rb +118 -0
  17. data/lib/devp2p/discovery/address.rb +83 -0
  18. data/lib/devp2p/discovery/kademlia_protocol_adapter.rb +11 -0
  19. data/lib/devp2p/discovery/node.rb +32 -0
  20. data/lib/devp2p/discovery/protocol.rb +342 -0
  21. data/lib/devp2p/discovery/transport.rb +105 -0
  22. data/lib/devp2p/exception.rb +30 -0
  23. data/lib/devp2p/frame.rb +197 -0
  24. data/lib/devp2p/kademlia.rb +48 -0
  25. data/lib/devp2p/kademlia/k_bucket.rb +178 -0
  26. data/lib/devp2p/kademlia/node.rb +40 -0
  27. data/lib/devp2p/kademlia/protocol.rb +284 -0
  28. data/lib/devp2p/kademlia/routing_table.rb +131 -0
  29. data/lib/devp2p/kademlia/wire_interface.rb +30 -0
  30. data/lib/devp2p/multiplexed_session.rb +110 -0
  31. data/lib/devp2p/multiplexer.rb +358 -0
  32. data/lib/devp2p/p2p_protocol.rb +170 -0
  33. data/lib/devp2p/packet.rb +35 -0
  34. data/lib/devp2p/peer.rb +329 -0
  35. data/lib/devp2p/peer_errors.rb +35 -0
  36. data/lib/devp2p/peer_manager.rb +274 -0
  37. data/lib/devp2p/rlpx_session.rb +434 -0
  38. data/lib/devp2p/sync_queue.rb +76 -0
  39. data/lib/devp2p/utils.rb +106 -0
  40. data/lib/devp2p/version.rb +13 -0
  41. data/lib/devp2p/wired_service.rb +30 -0
  42. metadata +227 -0
@@ -0,0 +1,76 @@
1
+ # -*- encoding : ascii-8bit -*-
2
+
3
+ ##
4
+ # A naive synchronized queue for Celluloid actors.
5
+ #
6
+ class SyncQueue
7
+
8
+ def initialize
9
+ @queue = []
10
+ @num_waiting = 0
11
+ @cond = Celluloid::Condition.new
12
+ end
13
+
14
+ def enq(obj)
15
+ @queue.push obj
16
+ @cond.signal
17
+ end
18
+ alias << enq
19
+
20
+ def deq(non_block=false)
21
+ loop do
22
+ if @queue.empty?
23
+ if non_block
24
+ raise ThreadError, 'queue empty'
25
+ else
26
+ begin
27
+ @num_waiting += 1
28
+ @cond.wait
29
+ ensure
30
+ @num_waiting -= 1
31
+ end
32
+ end
33
+ else
34
+ return @queue.shift
35
+ end
36
+ end
37
+ end
38
+
39
+ # Same as pop except it will not remove the element from queue, just peek.
40
+ def peek(non_block=false)
41
+ loop do
42
+ if @queue.empty?
43
+ if non_block
44
+ raise ThreadError, 'queue empty'
45
+ else
46
+ begin
47
+ @num_waiting += 1
48
+ @cond.wait
49
+ ensure
50
+ @num_waiting -= 1
51
+ end
52
+ end
53
+ else
54
+ return @queue[0]
55
+ end
56
+ end
57
+ end
58
+
59
+ def empty?
60
+ @queue.empty?
61
+ end
62
+
63
+ def clear
64
+ @queue.clear
65
+ end
66
+
67
+ def length
68
+ @queue.length
69
+ end
70
+ alias size length
71
+
72
+ # Returns the number of threads waiting on the queue.
73
+ def num_waiting
74
+ @num_waiting
75
+ end
76
+ end
@@ -0,0 +1,106 @@
1
+ # -*- encoding : ascii-8bit -*-
2
+
3
+ module DEVp2p
4
+ module Utils
5
+
6
+ BYTE_ZERO = "\x00".freeze
7
+
8
+ extend self
9
+
10
+ def encode_hex(b)
11
+ RLP::Utils.encode_hex b
12
+ end
13
+
14
+ def decode_hex(s)
15
+ RLP::Utils.decode_hex s
16
+ end
17
+
18
+ def int_to_big_endian(i)
19
+ RLP::Sedes.big_endian_int.serialize(i)
20
+ end
21
+
22
+ def big_endian_to_int(s)
23
+ RLP::Sedes.big_endian_int.deserialize s.sub(/\A(\x00)+/, '')
24
+ end
25
+
26
+ # 4 bytes big endian integer
27
+ def int_to_big_endian4(i)
28
+ [i].pack('I>')
29
+ end
30
+
31
+ def ceil16(x)
32
+ x % 16 == 0 ? x : (x + 16 - (x%16))
33
+ end
34
+
35
+ def lpad(x, symbol, l)
36
+ return x if x.size >= l
37
+ symbol * (l - x.size) + x
38
+ end
39
+
40
+ def zpad(x, l)
41
+ lpad x, BYTE_ZERO, l
42
+ end
43
+
44
+ def bpad(x, l)
45
+ lpad x.to_s(2), '0', l
46
+ end
47
+
48
+ def rzpad16(data)
49
+ extra = data.size % 16
50
+ data += "\x00" * (16 - extra) if extra != 0
51
+ data
52
+ end
53
+
54
+ def zpad_int(i, l=32)
55
+ Utils.zpad Utils.int_to_big_endian(i), l
56
+ end
57
+
58
+ ##
59
+ # String xor.
60
+ #
61
+ def sxor(s1, s2)
62
+ raise ArgumentError, "strings must have equal size" unless s1.size == s2.size
63
+
64
+ s1.bytes.zip(s2.bytes).map {|a, b| (a ^ b).chr }.join
65
+ end
66
+
67
+ def update_config_with_defaults(config, default_config)
68
+ default_config.each do |k, v|
69
+ if v.is_a?(Hash)
70
+ config[k] = update_config_with_defaults(config.fetch(k, {}), v)
71
+ elsif !config.has_key?(k)
72
+ config[k] = default_config[k]
73
+ end
74
+ end
75
+
76
+ config
77
+ end
78
+
79
+ def host_port_pubkey_from_uri(uri)
80
+ raise ArgumentError, 'invalid uri' unless uri =~ /\A#{NODE_URI_SCHEME}.+@.+:.+$/
81
+
82
+ pubkey_hex, ip_port = uri[NODE_URI_SCHEME.size..-1].split('@')
83
+ raise ArgumentError, 'invalid pubkey length' unless pubkey_hex.size == 2 * Kademlia::PUBKEY_SIZE / 8
84
+
85
+ ip, port = ip_port.split(':')
86
+ return ip, port, Utils.decode_hex(pubkey_hex)
87
+ end
88
+
89
+ def host_port_pubkey_to_uri(host, port, pubkey)
90
+ raise ArgumentError, 'invalid pubkey length' unless pubkey.size == Kademlia::PUBKEY_SIZE / 8
91
+
92
+ "#{NODE_URI_SCHEME}#{encode_hex pubkey}@#{host}:#{port}"
93
+ end
94
+
95
+ DOUBLE_COLON = '::'.freeze
96
+ def underscore(s)
97
+ word = s.split(DOUBLE_COLON).last
98
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
99
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
100
+ word.tr!("-", "_")
101
+ word.downcase!
102
+ word
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,13 @@
1
+ # -*- encoding : ascii-8bit -*-
2
+ module DEVp2p
3
+ VERSION = '0.1.0'
4
+
5
+ VersionString = begin
6
+ git_describe_re = /^(?<version>v\d+\.\d+\.\d+)-(?<git>\d+-g[a-fA-F0-9]+(?:-dirty)?)$/
7
+
8
+ rev = `git describe --tags --dirty`
9
+ m = rev.match git_describe_re
10
+
11
+ ver = m ? "#{m[:version]}+git-#{m[:git]}" : VERSION
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding : ascii-8bit -*-
2
+ module DEVp2p
3
+
4
+ ##
5
+ # A service which has an associated WireProtocol.
6
+ #
7
+ # peermanager checks all services registered with app.services
8
+ # if service is instance of WiredService
9
+ # add WiredService.wire_protocol to announced capabilities
10
+ # if a peer with the same protocol is connected
11
+ # a WiredService.wire_protocol instance is created
12
+ # with instances of Peer and WiredService
13
+ # WiredService.wire_protocol(Peer.new, WiredService.new)
14
+ #
15
+ class WiredService < BaseService
16
+ name 'wired'
17
+
18
+ attr_accessor :wire_protocol
19
+
20
+ def on_wire_protocol_start(proto)
21
+ raise ArgumentError, "argument is not a protocol" unless proto.is_a?(BaseProtocol)
22
+ end
23
+
24
+ def on_wire_protocol_stop(proto)
25
+ raise ArgumentError, "argument is not a protocol" unless proto.is_a?(BaseProtocol)
26
+ end
27
+
28
+ end
29
+
30
+ end
metadata ADDED
@@ -0,0 +1,227 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: devp2p
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jan Xie
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hashie
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: block_logger
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: celluloid
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.17'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.17'
55
+ - !ruby/object:Gem::Dependency
56
+ name: celluloid-io
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.17.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.17.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: digest-sha3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bitcoin-secp256k1
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 0.3.1
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 0.3.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: rlp
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 0.7.1
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 0.7.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '10.5'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '10.5'
125
+ - !ruby/object:Gem::Dependency
126
+ name: minitest
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '='
130
+ - !ruby/object:Gem::Version
131
+ version: 5.8.3
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '='
137
+ - !ruby/object:Gem::Version
138
+ version: 5.8.3
139
+ - !ruby/object:Gem::Dependency
140
+ name: yard
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '='
144
+ - !ruby/object:Gem::Version
145
+ version: 0.8.7.6
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '='
151
+ - !ruby/object:Gem::Version
152
+ version: 0.8.7.6
153
+ description: DEVp2p aims to provide a lightweight abstraction layer that provides
154
+ these low-level algorithms, protocols and services in a transparent framework without
155
+ predetermining the eventual transmission-use-cases of the protocols.
156
+ email:
157
+ - jan.h.xie@gmail.com
158
+ executables: []
159
+ extensions: []
160
+ extra_rdoc_files: []
161
+ files:
162
+ - LICENSE
163
+ - README.md
164
+ - lib/devp2p.rb
165
+ - lib/devp2p/app_helper.rb
166
+ - lib/devp2p/base_app.rb
167
+ - lib/devp2p/base_protocol.rb
168
+ - lib/devp2p/base_service.rb
169
+ - lib/devp2p/command.rb
170
+ - lib/devp2p/configurable.rb
171
+ - lib/devp2p/connection_monitor.rb
172
+ - lib/devp2p/control.rb
173
+ - lib/devp2p/crypto.rb
174
+ - lib/devp2p/crypto/ecc_x.rb
175
+ - lib/devp2p/crypto/ecies.rb
176
+ - lib/devp2p/discovery.rb
177
+ - lib/devp2p/discovery/address.rb
178
+ - lib/devp2p/discovery/kademlia_protocol_adapter.rb
179
+ - lib/devp2p/discovery/node.rb
180
+ - lib/devp2p/discovery/protocol.rb
181
+ - lib/devp2p/discovery/transport.rb
182
+ - lib/devp2p/exception.rb
183
+ - lib/devp2p/frame.rb
184
+ - lib/devp2p/kademlia.rb
185
+ - lib/devp2p/kademlia/k_bucket.rb
186
+ - lib/devp2p/kademlia/node.rb
187
+ - lib/devp2p/kademlia/protocol.rb
188
+ - lib/devp2p/kademlia/routing_table.rb
189
+ - lib/devp2p/kademlia/wire_interface.rb
190
+ - lib/devp2p/multiplexed_session.rb
191
+ - lib/devp2p/multiplexer.rb
192
+ - lib/devp2p/p2p_protocol.rb
193
+ - lib/devp2p/packet.rb
194
+ - lib/devp2p/peer.rb
195
+ - lib/devp2p/peer_errors.rb
196
+ - lib/devp2p/peer_manager.rb
197
+ - lib/devp2p/rlpx_session.rb
198
+ - lib/devp2p/sync_queue.rb
199
+ - lib/devp2p/utils.rb
200
+ - lib/devp2p/version.rb
201
+ - lib/devp2p/wired_service.rb
202
+ homepage: https://github.com/janx/ruby-devp2p
203
+ licenses:
204
+ - MIT
205
+ metadata: {}
206
+ post_install_message:
207
+ rdoc_options: []
208
+ require_paths:
209
+ - lib
210
+ required_ruby_version: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ required_rubygems_version: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - ">="
218
+ - !ruby/object:Gem::Version
219
+ version: '0'
220
+ requirements: []
221
+ rubyforge_project:
222
+ rubygems_version: 2.4.5.1
223
+ signing_key:
224
+ specification_version: 4
225
+ summary: A ruby implementation of Ethereum's DEVp2p framework.
226
+ test_files: []
227
+ has_rdoc: