specter 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 03a7593a58b7e476c274ddcc7a849c33d9251964
4
+ data.tar.gz: 61fdef93b66898a612708c4177e94f42501d237a
5
+ SHA512:
6
+ metadata.gz: dba4a51691b4390d6139c48c34940e71e5f2d455f8fae87ba73dc491cd16f4a3c7eed72d87c4409292b64df086201f6ee4b4eccd6ecc984887b034228c0c40b3
7
+ data.tar.gz: 37cdddbb000e0bd2c2bbf8fce8f139e2f66f1e8703bce3750be79abf6186baeb0681e03edea05bb4efac7b825ad4c85b639910f1aaec7879ef5c88c0fff12a81
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.1
@@ -0,0 +1,6 @@
1
+ ## specter 0.1.0
2
+
3
+ * Initial release with support for most *read* commands (ASICs and FPGAs
4
+ not included).
5
+
6
+ *Gabe Evans*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in specter.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Gabe Evans
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,37 @@
1
+ # (Pro)specter
2
+
3
+ Specter stubs a subset of cgminer's
4
+ [client protocol](https://github.com/ckolivas/cgminer/blob/master/API-README).
5
+ Use it to develop software that interacts with the API *without* being forced to
6
+ always run against a real, running instance.
7
+
8
+ ## Installation
9
+
10
+ Install it with:
11
+
12
+ $ gem install specter
13
+
14
+ Then start it with:
15
+
16
+ $ specter
17
+
18
+ ## Usage
19
+
20
+ ```
21
+ Usage: specter [options]
22
+ -H, --host HOST Bind to a specific address
23
+ -p, --port PORT Listen on a specific TCP port
24
+ -P, --proxy [HOST[:PORT]] Send unrecognized commands to an actual running miner
25
+ Host defaults to `localhost', port defaults to `4028'
26
+ -v, --version Show version information and exit
27
+ -h, --help Show this help message and exit
28
+ ```
29
+
30
+
31
+ ## Contributing
32
+
33
+ 1. Fork it (http://github.com/gevans/specter/fork)
34
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
35
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
36
+ 4. Push to the branch (`git push origin my-new-feature`)
37
+ 5. Create new Pull Request
@@ -0,0 +1,27 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ desc 'Generate a fixture for supplied command'
7
+ task :generate_fixture, [:command] do |t, args|
8
+ if args[:command].nil? || args[:command].empty?
9
+ abort 'no command specified'
10
+ end
11
+
12
+ command = args[:command].to_sym
13
+
14
+ require 'expedition'
15
+ client = Expedition::Client.new(
16
+ ENV['EXPEDITION_HOST'] || 'localhost',
17
+ ENV['EXPEDITION_PORT'] || 4028
18
+ )
19
+
20
+ fixture_path = File.expand_path("../lib/specter/fixtures/#{command}.json", __FILE__)
21
+ File.open(fixture_path, 'w') do |f|
22
+ f.write JSON.pretty_generate(client.send(command).raw)
23
+ end
24
+ puts "Wrote fixture to #{fixture_path}"
25
+ end
26
+
27
+ task default: :spec
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'specter'
4
+
5
+ Specter::Cli.start(ARGV)
@@ -0,0 +1,10 @@
1
+ require 'specter/version'
2
+ require 'specter/cli'
3
+ require 'specter/server'
4
+
5
+ module Specter
6
+
7
+ ##
8
+ # Raised when an incoming request is malformed in some way.
9
+ class RequestError < StandardError; end
10
+ end # Specter
@@ -0,0 +1,94 @@
1
+ require 'optparse'
2
+ require 'uri'
3
+
4
+ module Specter
5
+ class Cli
6
+
7
+ DEFAULT_HOST = '0.0.0.0'
8
+
9
+ DEFAULT_PORT = 5028
10
+
11
+ attr_reader :options
12
+
13
+ def initialize(argv)
14
+ @argv = argv
15
+ @options = {}
16
+ end
17
+
18
+ def self.start(argv)
19
+ new(argv).run
20
+ end
21
+
22
+ def output_header
23
+ puts "Booting Specter v#{VERSION}..."
24
+ puts "* Running in #{RUBY_DESCRIPTION}"
25
+ puts "* Listening on tcp://#{options[:host]}:#{options[:port]}"
26
+ puts 'Use Ctrl-C to stop'
27
+ end
28
+
29
+ def run
30
+ parse_options
31
+ output_header
32
+
33
+ @thread = @server.run
34
+ @thread.run
35
+
36
+ Signal.trap('INT') do
37
+ puts 'Stopping...'
38
+ @thread.exit
39
+ exit
40
+ end
41
+
42
+ @thread.join
43
+ end
44
+
45
+ private
46
+
47
+ def parse_options
48
+ @options = {
49
+ host: DEFAULT_HOST,
50
+ port: DEFAULT_PORT,
51
+ debug: true
52
+ }
53
+
54
+ parser = OptionParser.new do |opts|
55
+ opts.banner = 'Usage: specter [options]'
56
+
57
+ opts.on '-H', '--host HOST',
58
+ 'Bind to a specific address' do |arg|
59
+ options[:host] = arg
60
+ end
61
+
62
+ opts.on '-p', '--port PORT', 'Listen on a specific TCP port' do |arg|
63
+ options[:port] = Integer(arg)
64
+ end
65
+
66
+ opts.on '-P', '--proxy [HOST[:PORT]]', 'Send unrecognized commands to an actual running miner',
67
+ "Host defaults to `localhost', port defaults to `4028'" do |arg|
68
+ options[:proxy] = arg.to_s.split(':', 2)
69
+
70
+ case options[:proxy].size
71
+ when 0
72
+ options[:proxy] = ['localhost', 4028]
73
+ when 1
74
+ options[:proxy] << 4028
75
+ end
76
+ end
77
+
78
+ opts.on_tail '-v', '--version', 'Show version information and exit' do |arg|
79
+ puts "specter v#{Specter::VERSION}"
80
+ exit
81
+ end
82
+
83
+ opts.on_tail '-h', '--help', 'Show this help message and exit' do
84
+ puts opts
85
+ exit
86
+ end
87
+ end
88
+
89
+ parser.parse!(@argv)
90
+
91
+ @server = Server.new(self)
92
+ end
93
+ end # Cli
94
+ end # Specter
@@ -0,0 +1,22 @@
1
+ require 'forwardable'
2
+
3
+ module Specter
4
+ class Env < Hash
5
+ extend Forwardable
6
+
7
+ attr_reader :client
8
+
9
+ attr_reader :request
10
+
11
+ def_delegators :request, :command, :args
12
+
13
+ def initialize(client, request)
14
+ @client = client
15
+ @request = request
16
+ end
17
+
18
+ def to_str
19
+ "#{to_json}\x0"
20
+ end
21
+ end # Env
22
+ end # Specter
@@ -0,0 +1,21 @@
1
+ {
2
+ "STATUS": [
3
+ {
4
+ "STATUS": "S",
5
+ "When": 1397043350,
6
+ "Code": 78,
7
+ "Msg": "specter coin",
8
+ "Description": "specter 0.1.0"
9
+ }
10
+ ],
11
+ "COIN": [
12
+ {
13
+ "Hash Method": "scrypt",
14
+ "Current Block Time": 1397043315.715224,
15
+ "Current Block Hash": "43731fc6b8fe04dc579f6a5434330a4cfbcc674988202555fb39e54802ceae3e",
16
+ "LP": true,
17
+ "Network Difficulty": 62452873.65228917
18
+ }
19
+ ],
20
+ "id": 1
21
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "STATUS": [
3
+ {
4
+ "STATUS": "S",
5
+ "When": 1397042317,
6
+ "Code": 33,
7
+ "Msg": "specter config",
8
+ "Description": "specter 0.1.0"
9
+ }
10
+ ],
11
+ "CONFIG": [
12
+ {
13
+ "GPU Count": 3,
14
+ "Pool Count": 4,
15
+ "ADL": "Y",
16
+ "ADL in use": "Y",
17
+ "Strategy": "Failover",
18
+ "Log Interval": 5,
19
+ "Device Code": "GPU ",
20
+ "OS": "Linux",
21
+ "Failover-Only": true,
22
+ "ScanTime": 60,
23
+ "Queue": 1,
24
+ "Expiry": 120
25
+ }
26
+ ],
27
+ "id": 1
28
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "STATUS": [
3
+ {
4
+ "STATUS": "S",
5
+ "When": 1397042151,
6
+ "Code": 69,
7
+ "Msg": "Device Details",
8
+ "Description": "specter 0.1.0"
9
+ }
10
+ ],
11
+ "DEVDETAILS": [
12
+ {
13
+ "DEVDETAILS": 0,
14
+ "Name": "GPU",
15
+ "ID": 0,
16
+ "Driver": "opencl",
17
+ "Kernel": "ckolivas",
18
+ "Model": "AMD Radeon R9 200 Series",
19
+ "Device Path": ""
20
+ },
21
+ {
22
+ "DEVDETAILS": 1,
23
+ "Name": "GPU",
24
+ "ID": 1,
25
+ "Driver": "opencl",
26
+ "Kernel": "ckolivas",
27
+ "Model": "AMD Radeon R9 200 Series",
28
+ "Device Path": ""
29
+ },
30
+ {
31
+ "DEVDETAILS": 2,
32
+ "Name": "GPU",
33
+ "ID": 2,
34
+ "Driver": "opencl",
35
+ "Kernel": "ckolivas",
36
+ "Model": "AMD Radeon R9 200 Series",
37
+ "Device Path": ""
38
+ }
39
+ ],
40
+ "id": 1
41
+ }
@@ -0,0 +1,113 @@
1
+ {
2
+ "STATUS": [
3
+ {
4
+ "STATUS": "S",
5
+ "When": 1397042125,
6
+ "Code": 9,
7
+ "Msg": "3 GPU(s)",
8
+ "Description": "specter 0.1.0"
9
+ }
10
+ ],
11
+ "DEVS": [
12
+ {
13
+ "GPU": 0,
14
+ "Enabled": "Y",
15
+ "Status": "Alive",
16
+ "Temperature": 76.0,
17
+ "Fan Speed": -1,
18
+ "Fan Percent": 99,
19
+ "GPU Clock": 948,
20
+ "Memory Clock": 1500,
21
+ "GPU Voltage": 0.0,
22
+ "GPU Activity": 100,
23
+ "Powertune": 30,
24
+ "MHS av": 0.9291,
25
+ "MHS 5s": 0.9309,
26
+ "KHS av": 929,
27
+ "KHS 5s": 931,
28
+ "Accepted": 1147,
29
+ "Rejected": 1,
30
+ "Hardware Errors": 0,
31
+ "Utility": 1.6732,
32
+ "Intensity": "0",
33
+ "Last Share Pool": 0,
34
+ "Last Share Time": 1397042089,
35
+ "Total MH": 38214.9898,
36
+ "Diff1 Work": 589212,
37
+ "Difficulty Accepted": 587264.0,
38
+ "Difficulty Rejected": 512.0,
39
+ "Last Share Difficulty": 512.0,
40
+ "Last Valid Work": 1397042089,
41
+ "Device Hardware%": 0.0,
42
+ "Device Rejected%": 0.0869,
43
+ "Device Elapsed": 41130
44
+ },
45
+ {
46
+ "GPU": 1,
47
+ "Enabled": "Y",
48
+ "Status": "Alive",
49
+ "Temperature": 76.0,
50
+ "Fan Speed": -1,
51
+ "Fan Percent": 99,
52
+ "GPU Clock": 916,
53
+ "Memory Clock": 1500,
54
+ "GPU Voltage": 0.0,
55
+ "GPU Activity": 100,
56
+ "Powertune": 30,
57
+ "MHS av": 0.9099,
58
+ "MHS 5s": 0.9117,
59
+ "KHS av": 910,
60
+ "KHS 5s": 912,
61
+ "Accepted": 1106,
62
+ "Rejected": 2,
63
+ "Hardware Errors": 0,
64
+ "Utility": 1.6134,
65
+ "Intensity": "0",
66
+ "Last Share Pool": 0,
67
+ "Last Share Time": 1397042114,
68
+ "Total MH": 37423.4573,
69
+ "Diff1 Work": 565927,
70
+ "Difficulty Accepted": 566272.0,
71
+ "Difficulty Rejected": 1024.0,
72
+ "Last Share Difficulty": 512.0,
73
+ "Last Valid Work": 1397042114,
74
+ "Device Hardware%": 0.0,
75
+ "Device Rejected%": 0.1809,
76
+ "Device Elapsed": 41130
77
+ },
78
+ {
79
+ "GPU": 2,
80
+ "Enabled": "Y",
81
+ "Status": "Alive",
82
+ "Temperature": 76.0,
83
+ "Fan Speed": -1,
84
+ "Fan Percent": 97,
85
+ "GPU Clock": 952,
86
+ "Memory Clock": 1500,
87
+ "GPU Voltage": 0.0,
88
+ "GPU Activity": 100,
89
+ "Powertune": 30,
90
+ "MHS av": 0.9295,
91
+ "MHS 5s": 0.9308,
92
+ "KHS av": 930,
93
+ "KHS 5s": 931,
94
+ "Accepted": 1174,
95
+ "Rejected": 3,
96
+ "Hardware Errors": 0,
97
+ "Utility": 1.7126,
98
+ "Intensity": "0",
99
+ "Last Share Pool": 0,
100
+ "Last Share Time": 1397042096,
101
+ "Total MH": 38230.613,
102
+ "Diff1 Work": 604241,
103
+ "Difficulty Accepted": 601088.0,
104
+ "Difficulty Rejected": 1536.0,
105
+ "Last Share Difficulty": 512.0,
106
+ "Last Valid Work": 1397042096,
107
+ "Device Hardware%": 0.0,
108
+ "Device Rejected%": 0.2542,
109
+ "Device Elapsed": 41130
110
+ }
111
+ ],
112
+ "id": 1
113
+ }