pickynode 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -0
- data/README.md +3 -3
- data/bin/pickynode +1 -0
- data/lib/pickynode.rb +13 -4
- data/pickynode.gemspec +1 -0
- data/spec/mocks.rb +16 -0
- data/spec/pickynode_spec.rb +91 -6
- data/spec/spec_helper.rb +6 -0
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d49df9c54a1dd3799f0b66b74f75f217560f283d
|
4
|
+
data.tar.gz: 5cba4b0edea26ba858cb83dd2128d4b4cc45b71d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01e9aa203431912c58a97b78920c685e146f5150d0d1ee18d70999c702b17ec092bdfe480905345a1dace8318ee6fecb3c990ef3ca17c5041b5388ddad1ba52d
|
7
|
+
data.tar.gz: d09e13a8f1cb105907833dc8fa69fdff3063a6e7791d70200b72d6ad8319e5639d01da3ee1775d1ff41d81a1f1dfa036bf3108f0b8b2349f546b428ba9755df8
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -4,6 +4,8 @@ GEM
|
|
4
4
|
ast (2.3.0)
|
5
5
|
awesome_print (1.7.0)
|
6
6
|
diff-lcs (1.3)
|
7
|
+
docile (1.1.5)
|
8
|
+
json (2.1.0)
|
7
9
|
parser (2.4.0.0)
|
8
10
|
ast (~> 2.2)
|
9
11
|
powerpack (0.1.1)
|
@@ -30,6 +32,11 @@ GEM
|
|
30
32
|
ruby-progressbar (~> 1.7)
|
31
33
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
32
34
|
ruby-progressbar (1.8.1)
|
35
|
+
simplecov (0.14.1)
|
36
|
+
docile (~> 1.1.0)
|
37
|
+
json (>= 1.8, < 3)
|
38
|
+
simplecov-html (~> 0.10.0)
|
39
|
+
simplecov-html (0.10.1)
|
33
40
|
trollop (2.1.2)
|
34
41
|
unicode-display_width (1.2.1)
|
35
42
|
|
@@ -41,6 +48,7 @@ DEPENDENCIES
|
|
41
48
|
rake (~> 12.0)
|
42
49
|
rspec (~> 3.6)
|
43
50
|
rubocop (~> 0.48)
|
51
|
+
simplecov (~> 0.14)
|
44
52
|
trollop (~> 2.1)
|
45
53
|
|
46
54
|
RUBY VERSION
|
data/README.md
CHANGED
@@ -45,17 +45,17 @@ pickynode --disconnect=USER_AGENT_FILTER
|
|
45
45
|
### Help:
|
46
46
|
|
47
47
|
```
|
48
|
-
pickynode v0.1.
|
48
|
+
pickynode v0.1.2
|
49
49
|
Options:
|
50
50
|
-a, --add=<s> Add node type
|
51
51
|
-c, --connect=<s> Connect to node type
|
52
52
|
-b, --ban=<s> Ban node type
|
53
53
|
-d, --debug Debug mode
|
54
|
+
-i, --info Local node info
|
54
55
|
-o, --output Output commands
|
55
|
-
-
|
56
|
+
-s, --disconnect=<s> Disconnect from node type
|
56
57
|
-v, --version Print version and exit
|
57
58
|
-h, --help Show this message
|
58
|
-
|
59
59
|
```
|
60
60
|
|
61
61
|
The --add and --connect commands pull data from Bitnodes.
|
data/bin/pickynode
CHANGED
@@ -9,6 +9,7 @@ opts = Trollop.options do
|
|
9
9
|
opt :connect, 'Connect to node type', type: :string
|
10
10
|
opt :ban, 'Ban node type', type: :string
|
11
11
|
opt :debug, 'Debug mode'
|
12
|
+
opt :info, 'Local node info'
|
12
13
|
opt :output, 'Output commands'
|
13
14
|
opt :disconnect, 'Disconnect from node type', type: :string
|
14
15
|
end
|
data/lib/pickynode.rb
CHANGED
@@ -9,7 +9,7 @@ require 'uri'
|
|
9
9
|
# Allows you to easily add/ban/connect/disconnect nodes
|
10
10
|
# based on User Agent.
|
11
11
|
class Pickynode
|
12
|
-
VERSION = '0.1.
|
12
|
+
VERSION = '0.1.2'
|
13
13
|
|
14
14
|
def initialize(opts = {})
|
15
15
|
@opts = opts
|
@@ -50,6 +50,10 @@ class Pickynode
|
|
50
50
|
ap addr_types
|
51
51
|
end
|
52
52
|
|
53
|
+
def info
|
54
|
+
ap getinfo
|
55
|
+
end
|
56
|
+
|
53
57
|
def run
|
54
58
|
add(@opts[:add])
|
55
59
|
connect(@opts[:connect])
|
@@ -57,9 +61,8 @@ class Pickynode
|
|
57
61
|
ban(@opts[:ban])
|
58
62
|
disconnect(@opts[:disconnect])
|
59
63
|
|
60
|
-
|
61
|
-
|
62
|
-
display
|
64
|
+
info if @opts[:info]
|
65
|
+
display if @opts.values.select { |v| v }.empty?
|
63
66
|
end
|
64
67
|
|
65
68
|
def clear_cache
|
@@ -99,6 +102,12 @@ class Pickynode
|
|
99
102
|
Net::HTTP.get(URI.parse('https://bitnodes.21.co/api/v1/snapshots/latest/'))
|
100
103
|
end
|
101
104
|
|
105
|
+
def getinfo
|
106
|
+
JSON.parse(`bitcoin-cli getinfo`)
|
107
|
+
rescue JSON::ParserError
|
108
|
+
{}
|
109
|
+
end
|
110
|
+
|
102
111
|
def getpeerinfo
|
103
112
|
`bitcoin-cli getpeerinfo`
|
104
113
|
end
|
data/pickynode.gemspec
CHANGED
data/spec/mocks.rb
CHANGED
@@ -12,6 +12,22 @@ BITNODES_SNAPSHOT = <<-HEREDOC
|
|
12
12
|
}
|
13
13
|
HEREDOC
|
14
14
|
|
15
|
+
NODE_INFO = <<-HEREDOC
|
16
|
+
{
|
17
|
+
"version": 1020500,
|
18
|
+
"protocolversion": 70012,
|
19
|
+
"blocks": 467548,
|
20
|
+
"timeoffset": 0,
|
21
|
+
"connections": 154,
|
22
|
+
"proxy": "",
|
23
|
+
"difficulty": 559970892890.8381,
|
24
|
+
"testnet": false,
|
25
|
+
"paytxfee": 0.00000000,
|
26
|
+
"relayfee": 0.00001000,
|
27
|
+
"errors": ""
|
28
|
+
}
|
29
|
+
HEREDOC
|
30
|
+
|
15
31
|
PEER_INFO = <<-HEREDOC
|
16
32
|
[
|
17
33
|
{
|
data/spec/pickynode_spec.rb
CHANGED
@@ -19,6 +19,12 @@ describe Pickynode do
|
|
19
19
|
ipv6_ip => '/SecondClient/' }
|
20
20
|
end
|
21
21
|
|
22
|
+
# String to simulate a json error.
|
23
|
+
let(:json_error) { 'An error occurred.' }
|
24
|
+
|
25
|
+
# Parsed information from getinfo.
|
26
|
+
let(:parsed_node_info) { JSON.parse(NODE_INFO) }
|
27
|
+
|
22
28
|
subject { Pickynode.new(opts) }
|
23
29
|
|
24
30
|
describe '.add' do
|
@@ -39,11 +45,18 @@ describe Pickynode do
|
|
39
45
|
subject.add(false)
|
40
46
|
subject.add(nil)
|
41
47
|
end
|
48
|
+
|
49
|
+
it 'should recover gracefully if json is malformed' do
|
50
|
+
expect(subject).to receive(:bitnodes_snapshot).once
|
51
|
+
.and_return(json_error)
|
52
|
+
expect(subject).to_not receive(:run_cmd)
|
53
|
+
subject.add('Anything')
|
54
|
+
end
|
42
55
|
end
|
43
56
|
|
44
57
|
describe '.ban' do
|
45
58
|
it 'should ban nodes based on user agent' do
|
46
|
-
expect(subject).to receive(
|
59
|
+
expect(subject).to receive(:`).once
|
47
60
|
.and_return(PEER_INFO)
|
48
61
|
expect(URI).to receive(:parse).with('https://131.114.88.218:33422')
|
49
62
|
.and_call_original
|
@@ -64,6 +77,13 @@ describe Pickynode do
|
|
64
77
|
subject.ban(false)
|
65
78
|
subject.ban(nil)
|
66
79
|
end
|
80
|
+
|
81
|
+
it 'should recover gracefully if json is malformed' do
|
82
|
+
expect(subject).to receive(:`).once
|
83
|
+
.and_return(json_error)
|
84
|
+
expect(subject).to_not receive(:run_cmd)
|
85
|
+
subject.ban('Anything')
|
86
|
+
end
|
67
87
|
end
|
68
88
|
|
69
89
|
describe '.connect' do
|
@@ -84,11 +104,18 @@ describe Pickynode do
|
|
84
104
|
subject.connect(false)
|
85
105
|
subject.connect(nil)
|
86
106
|
end
|
107
|
+
|
108
|
+
it 'should recover gracefully if json is malformed' do
|
109
|
+
expect(subject).to receive(:bitnodes_snapshot).once
|
110
|
+
.and_return(json_error)
|
111
|
+
expect(subject).to_not receive(:run_cmd)
|
112
|
+
subject.connect('Anything')
|
113
|
+
end
|
87
114
|
end
|
88
115
|
|
89
116
|
describe '.disconnect' do
|
90
117
|
it 'should disconnect nodes based on user agent' do
|
91
|
-
expect(subject).to receive(
|
118
|
+
expect(subject).to receive(:`).once
|
92
119
|
.and_return(PEER_INFO)
|
93
120
|
expect(subject).to receive(:run_cmd)
|
94
121
|
.with(%(bitcoin-cli disconnectnode "#{ipv6_ip}"))
|
@@ -104,14 +131,46 @@ describe Pickynode do
|
|
104
131
|
subject.disconnect(false)
|
105
132
|
subject.disconnect(nil)
|
106
133
|
end
|
134
|
+
|
135
|
+
it 'should recover gracefully if json is malformed' do
|
136
|
+
expect(subject).to receive(:`).once
|
137
|
+
.and_return(json_error)
|
138
|
+
expect(subject).to_not receive(:run_cmd)
|
139
|
+
subject.disconnect('Anything')
|
140
|
+
end
|
107
141
|
end
|
108
142
|
|
109
143
|
describe '.display' do
|
110
144
|
it 'should display connected nodes' do
|
111
|
-
expect(subject).to receive(
|
145
|
+
expect(subject).to receive(:`).once
|
146
|
+
.and_return(PEER_INFO)
|
112
147
|
expect(subject).to receive(:ap).with(node_hash).and_return(node_hash)
|
113
148
|
expect(subject.display).to eq(node_hash)
|
114
149
|
end
|
150
|
+
|
151
|
+
it 'should recover gracefully if json is malformed' do
|
152
|
+
expect(subject).to receive(:`).once
|
153
|
+
.and_return(json_error)
|
154
|
+
expect(subject).to receive(:ap).with({}).and_return({})
|
155
|
+
expect(subject.display).to eq({})
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe '.info' do
|
160
|
+
it 'should display local node info' do
|
161
|
+
expect(subject).to receive(:`).once
|
162
|
+
.and_return(NODE_INFO)
|
163
|
+
expect(subject).to receive(:ap).with(parsed_node_info)
|
164
|
+
.and_return(parsed_node_info)
|
165
|
+
expect(subject.info).to eq(parsed_node_info)
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'should recover gracefully if json is malformed' do
|
169
|
+
expect(subject).to receive(:`).once
|
170
|
+
.and_return(json_error)
|
171
|
+
expect(subject).to receive(:ap).with({}).and_return({})
|
172
|
+
expect(subject.info).to eq({})
|
173
|
+
end
|
115
174
|
end
|
116
175
|
|
117
176
|
describe '.run' do
|
@@ -119,6 +178,7 @@ describe Pickynode do
|
|
119
178
|
let(:opts) do
|
120
179
|
{
|
121
180
|
debug: true,
|
181
|
+
info: true,
|
122
182
|
add: 'Wanted',
|
123
183
|
connect: 'Now',
|
124
184
|
ban: 'Nefarious',
|
@@ -126,10 +186,11 @@ describe Pickynode do
|
|
126
186
|
}
|
127
187
|
end
|
128
188
|
|
129
|
-
it 'should call add, connect, ban and
|
189
|
+
it 'should call add, connect, ban, disconnect and info' do
|
130
190
|
expect(subject).to receive(:bitnodes_snapshot).once
|
131
191
|
.and_return(BITNODES_SNAPSHOT)
|
132
|
-
expect(subject).to receive(:getpeerinfo).
|
192
|
+
expect(subject).to receive(:getpeerinfo).once
|
193
|
+
.and_return(PEER_INFO)
|
133
194
|
expect(subject).to receive(:add).with(opts[:add])
|
134
195
|
.and_call_original
|
135
196
|
expect(subject).to receive(:connect).with(opts[:connect])
|
@@ -138,9 +199,24 @@ describe Pickynode do
|
|
138
199
|
.and_call_original
|
139
200
|
expect(subject).to receive(:disconnect).with(opts[:disconnect])
|
140
201
|
.and_call_original
|
202
|
+
expect(subject).to receive(:info)
|
141
203
|
expect(subject).to_not receive(:display)
|
142
204
|
subject.run
|
143
205
|
end
|
206
|
+
|
207
|
+
it 'should recover gracefully if json is malformed' do
|
208
|
+
expect(subject).to receive(:bitnodes_snapshot).at_least(1)
|
209
|
+
.and_return(json_error)
|
210
|
+
expect(subject).to receive(:getpeerinfo).at_least(1)
|
211
|
+
.and_return(json_error)
|
212
|
+
expect(subject).to receive(:`)
|
213
|
+
.and_return(json_error)
|
214
|
+
expect(subject).to receive(:info)
|
215
|
+
.and_call_original
|
216
|
+
expect(subject).to receive(:ap).with({})
|
217
|
+
expect(subject).to_not receive(:run_cmd)
|
218
|
+
subject.run
|
219
|
+
end
|
144
220
|
end
|
145
221
|
|
146
222
|
context 'without opts' do
|
@@ -149,12 +225,21 @@ describe Pickynode do
|
|
149
225
|
end
|
150
226
|
|
151
227
|
it 'should call display' do
|
152
|
-
expect(subject).to receive(
|
228
|
+
expect(subject).to receive(:`).once
|
153
229
|
.and_return(PEER_INFO)
|
154
230
|
expect(subject).to receive(:ap).with(node_hash).and_return(node_hash)
|
155
231
|
expect(subject).to receive(:display).and_call_original
|
156
232
|
subject.run
|
157
233
|
end
|
234
|
+
|
235
|
+
it 'should recover gracefully if json is malformed' do
|
236
|
+
expect(subject).to receive(:`).once
|
237
|
+
.and_return(json_error)
|
238
|
+
expect(subject).to_not receive(:run_cmd)
|
239
|
+
expect(subject).to_not receive(:info)
|
240
|
+
expect(subject).to receive(:ap).with({}).and_return({})
|
241
|
+
subject.run
|
242
|
+
end
|
158
243
|
end
|
159
244
|
end
|
160
245
|
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pickynode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Ellithorpe
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0.48'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.14'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.14'
|
83
97
|
description: Some people are picky about the bitcoin nodes they connect to.
|
84
98
|
email: quest@mac.com
|
85
99
|
executables:
|