txcatcher 0.1.85 → 0.1.86

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b38221c572549590a66aeee17bd40d9faf33cd23
4
- data.tar.gz: 2f23c67720cc64544ed1feda49c656f5fca4e538
3
+ metadata.gz: 965c94026bab04e89b4371d58f6a4025ed22d2e1
4
+ data.tar.gz: d01ca825c2f1e0670a131c5d971d2452ce3b3f55
5
5
  SHA512:
6
- metadata.gz: c895162372eacf4102e6cf051e897a0af141fe4779e5865635121ebb57036954f6fd48f3e370cfa323a9795788cd0b5815ffec8a34a4c29962094bb82d924ead
7
- data.tar.gz: 73141d20ac2af88b1cbafbff568becbf8349ecb87df09ecebe58431ccb459c5325be8446076fd6277e5cee9a8eeb0c0911fd8a20cad06a36db1c98342cbd16ec
6
+ metadata.gz: dc4da965fd01031c17163e97518bfffcd1edb1be06a68a7e7b8cfa3c9f7e65d5394434c2d5cd346127a596e843487107d1076e5b443ea8d66dcf27f8108b9b18
7
+ data.tar.gz: c77d3e23861d9d619748842b10e3c809c8e4f8343051826f4803e54023cc09c8f152ebb191c476de509cd5c4276fe29e96b356f8fd92a0ae07b4863b4215b414
data/Gemfile CHANGED
@@ -5,6 +5,8 @@ gem "sequel"
5
5
  gem "ffi-rzmq"
6
6
  gem "crypto-unit"
7
7
  gem "sentry-raven"
8
+ gem "aws-sdk-ses"
9
+ gem "faraday"
8
10
 
9
11
  group :development do
10
12
  gem "bundler"
data/Gemfile.lock CHANGED
@@ -4,6 +4,15 @@ GEM
4
4
  addressable (2.4.0)
5
5
  async-rack (0.5.1)
6
6
  rack (~> 1.1)
7
+ aws-partitions (1.68.0)
8
+ aws-sdk-core (3.17.0)
9
+ aws-partitions (~> 1.0)
10
+ aws-sigv4 (~> 1.0)
11
+ jmespath (~> 1.0)
12
+ aws-sdk-ses (1.6.0)
13
+ aws-sdk-core (~> 3)
14
+ aws-sigv4 (~> 1.0)
15
+ aws-sigv4 (1.0.2)
7
16
  builder (3.2.3)
8
17
  crypto-unit (0.3.3)
9
18
  descendants_tracker (0.0.4)
@@ -57,6 +66,7 @@ GEM
57
66
  rake
58
67
  rdoc
59
68
  semver2
69
+ jmespath (1.3.1)
60
70
  jwt (1.5.6)
61
71
  log4r (1.1.10)
62
72
  mime-types (2.99.3)
@@ -105,8 +115,10 @@ PLATFORMS
105
115
  ruby
106
116
 
107
117
  DEPENDENCIES
118
+ aws-sdk-ses
108
119
  bundler
109
120
  crypto-unit
121
+ faraday
110
122
  ffi-rzmq
111
123
  goliath
112
124
  jeweler
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.85
1
+ 0.1.86
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This script is designed to be launched with cron every n minutes to knock on
4
+ # txcatcher's API and check whether new transactions are being picked up by it.
5
+ #
6
+ # New transactions are being fetched from a third-party source (currently: blockcypher.com)
7
+ # and config is read from the same config file as the one txcatcher uses.
8
+ #
9
+ # If an incosistency is found, reports are sent to email and to the logfile
10
+ # placed in your config_dir/txcatcher_monitor_errors.log
11
+ # Successful checks are logged into config_dir/txcatcher_monitor.log
12
+ #
13
+ # To run this script, specify config dir like this:
14
+ #
15
+ # txcatcher-monitor -c ~/.txcatcher/
16
+ #
17
+ # or
18
+ #
19
+ # txcatcher-monitor --config-dir ~/.txcatcher/
20
+ #
21
+ # When you generated an example config file with txcatcher on the first run,
22
+ # you should look at "monitor" section for settings related to this script.
23
+ #
24
+ # Just in case, here they are:
25
+ #
26
+ # monitor:
27
+ # txcatcher_url: "https://txcatcher-btc-mainnet.mydomain.com"
28
+ # blockchain_source_url: "https://api.blockcypher.com/v1/btc/main/txs"
29
+ # aws_ses:
30
+ # region: 'us-west-2'
31
+ # access_key: YOUR_AWS_KEY
32
+ # secret_access_key: YOUR_AWS_SECRET_ACCESS_KEY
33
+ # alert_mail:
34
+ # from: "alert@email.com"
35
+ # to:
36
+ # - "your@email.com"
37
+ # subject: "TxCatcher Alert"
38
+ #
39
+ # However remember, you'll also need a 'logger' section in this file.
40
+
41
+ require "rubygems"
42
+ require "faraday"
43
+ require "aws-sdk-ses"
44
+ require "yaml"
45
+ require 'time'
46
+ require_relative "../lib/txcatcher/config"
47
+ require_relative "../lib/txcatcher/logger"
48
+ require_relative "../lib/txcatcher/initializer"
49
+
50
+ def send_alert(subject, text)
51
+
52
+ return unless TxCatcher::Config["monitor"]["alert_mail"]
53
+
54
+ # Do not send emails more often than once in 1 hour
55
+ email_time_file = TxCatcher::Config.config_dir + "/txcatcher_monitor_last_email_time.txt"
56
+ t = Time.parse(File.read(email_time_file)) if File.exists?(email_time_file)
57
+ return if t && t > Time.now - 3600
58
+
59
+ ses_config = TxCatcher::Config["monitor"]["aws_ses"]
60
+ ses = Aws::SES::Client.new(
61
+ region: ses_config["region"],
62
+ access_key_id: ses_config["access_key"],
63
+ secret_access_key: ses_config["secret_access_key"]
64
+ )
65
+
66
+ resp = ses.send_email({
67
+ destination: { to_addresses: TxCatcher::Config["monitor"]["alert_mail"]["to"] },
68
+ source: TxCatcher::Config["monitor"]["alert_mail"]["from"],
69
+ message: {
70
+ body: { text: { charset: "utf-8", data: text }},
71
+ subject: { charset: "utf-8", data: subject }
72
+ }
73
+ })
74
+
75
+ File.open(email_time_file, 'w') { |f| f.write Time.now.to_s }
76
+
77
+ end
78
+
79
+ def latest_output_addr
80
+
81
+ response = Faraday.get do |req|
82
+ req.url TxCatcher::Config["monitor"]["blockchain_source_url"]
83
+ req.options.timeout = 5
84
+ req.options.open_timeout = 5
85
+ end
86
+ txs = JSON.parse(response.body)
87
+
88
+ txs.each do |tx|
89
+ if tx["outputs"] && tx["outputs"].first["addresses"]
90
+ tx["outputs"].first["addresses"].each do |addr|
91
+ # Blockcypher returns old Litecoin P2SH addresses which start with 3, which
92
+ # txcatcher doesn't support. Let's just ignore them.
93
+ if addr[0] != "3" || !TxCatcher::Config["monitor"]["ignore_3_litecoin_addr"]
94
+ return addr
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ end
101
+
102
+ def try_txcatcher(addr, sleep_time: 3)
103
+
104
+ raise StandardError
105
+
106
+ url = TxCatcher::Config["monitor"]["txcatcher_url"] + "/addr/#{addr}/utxo"
107
+
108
+ response = {}
109
+ 3.times do
110
+ sleep sleep_time # let's wait, perhaps txcatcher hasn't caught up
111
+ break unless (response = fetch_txcatcher_for_addr(addr)).empty?
112
+ end
113
+
114
+ if response.empty?
115
+ send_alert(
116
+ "TxCatcher response empty",
117
+ "TxCatcher returned an empty {} for #{url}"
118
+ )
119
+ TxCatcher::Logger.report("Checked #{url}, got empty response", :error)
120
+ else
121
+ TxCatcher::Logger.report("Checked #{url}, got #{response.size} utxos", :info)
122
+ end
123
+
124
+ end
125
+
126
+ def fetch_txcatcher_for_addr(addr)
127
+ response = Faraday.get do |req|
128
+ req.url TxCatcher::Config["monitor"]["txcatcher_url"] + "/addr/#{addr}1/utxo"
129
+ req.options.timeout = 5
130
+ req.options.open_timeout = 5
131
+ end
132
+ JSON.parse(response.body)
133
+ end
134
+
135
+ begin
136
+ include TxCatcher::Initializer
137
+ ConfigFile.set!
138
+ TxCatcher::Logger.set_log_file_names!(log: "txcatcher_monitor.log", error: "txcatcher_monitor_errors.log")
139
+ read_config_file
140
+ try_txcatcher(latest_output_addr)
141
+ rescue StandardError => e
142
+ TxCatcher::Logger.report(e, :error)
143
+ send_alert(
144
+ "TxCatcher monitor error",
145
+ "While checking #{TxCatcher::Config["monitor"]["txcatcher_url"]} response, got the following error\n\n" +
146
+ "#{e.to_s}\n\n#{e.backtrace.join("\n")}"
147
+ )
148
+ end
@@ -10,8 +10,16 @@ module TxCatcher
10
10
  unknown: 5
11
11
  }
12
12
 
13
+ @@log_file_name = "txcatcher.log"
14
+ @@error_log_file_name = "error.log"
15
+
13
16
  class << self
14
17
 
18
+ def set_log_file_names!(log: nil, error: nil)
19
+ @@log_file_name = log if log
20
+ @@error_log_file_name = error if error
21
+ end
22
+
15
23
  def report(message, log_level=:info, data: nil, timestamp: false)
16
24
  [:logfile, :stdout, :sentry].each do |out|
17
25
  if LOG_LEVELS[log_level] >= LOG_LEVELS[Config["logger"]["#{out}_level"].to_sym]
@@ -29,7 +37,7 @@ module TxCatcher
29
37
  end
30
38
 
31
39
  def report_to_logfile(message, log_level, data: nil, timestamp: true) # always gonna be forcing timestamp to be true here
32
- fn = LOG_LEVELS[log_level] >= LOG_LEVELS[:error] ? "error.log" : "txcatcher.log"
40
+ fn = LOG_LEVELS[log_level] >= LOG_LEVELS[:error] ? @@error_log_file_name : @@log_file_name
33
41
  fn = TxCatcher::Config.config_dir + "/#{fn}"
34
42
 
35
43
  File.open(fn, "a") do |f|
@@ -40,6 +48,7 @@ module TxCatcher
40
48
  end
41
49
 
42
50
  def report_to_sentry(e, log_level, data: nil, timestamp: timestamp)
51
+ return unless TxCatcher::Config["logger"]["sentry_dsn"]
43
52
  data ||= {}
44
53
  data.merge!(environment: Config["environment"], host: Config["host"], currency: Config["currency"])
45
54
  Raven.tags_context data
data/templates/config.yml CHANGED
@@ -24,6 +24,24 @@ logger:
24
24
  sentry_level: error
25
25
  sentry_dsn: null
26
26
 
27
+ monitor:
28
+ # REPLACE with your txcatcher url
29
+ txcatcher_url: "https://txcatcher-btc-mainnet.mydomain.com"
30
+
31
+ # LEAVE as is if on bitcoin mainnet, replace with
32
+ # https://api.blockcypher.com/v1/ltc/main/txs for Litecoin
33
+ # https://api.blockcypher.com/v1/btc/test3/txs for Bitcoin TESTNET
34
+ blockchain_source_url: "https://api.blockcypher.com/v1/btc/main/txs"
35
+ aws_ses:
36
+ region: 'us-west-2'
37
+ access_key: YOUR_AWS_KEY
38
+ secret_access_key: YOUR_AWS_SECRET_ACCESS_KEY
39
+ alert_mail:
40
+ from: "alert@email.com"
41
+ to:
42
+ - "your@email.com"
43
+ subject: "TxCatcher Alert"
44
+
27
45
  zeromq: bitcoind
28
46
  max_db_transactions_stored: 100000
29
47
  db_clean_period_seconds: 300
data/txcatcher.gemspec CHANGED
@@ -2,19 +2,19 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: txcatcher 0.1.85 ruby lib
5
+ # stub: txcatcher 0.1.86 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "txcatcher"
9
- s.version = "0.1.85"
9
+ s.version = "0.1.86"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Roman Snitko"]
14
- s.date = "2017-09-25"
15
- s.description = "Currently, the only job of this gem is to collect all new Bitcoin/Litecoin transactions, store them in a DB, index addresses."
14
+ s.date = "2018-03-05"
15
+ s.description = "Ccurrently, the only job of this gem is to collect all new Bitcoin/Litecoin transactions, store them in a DB, index addresses."
16
16
  s.email = "roman.snitko@gmail.com"
17
- s.executables = ["goliath.log", "goliath_stdout.log", "txcatcher"]
17
+ s.executables = ["txcatcher", "txcatcher-monitor"]
18
18
  s.extra_rdoc_files = [
19
19
  "LICENSE.txt",
20
20
  "README.md"
@@ -28,12 +28,13 @@ Gem::Specification.new do |s|
28
28
  "README.md",
29
29
  "Rakefile",
30
30
  "VERSION",
31
- "bin/goliath.log",
32
- "bin/goliath_stdout.log",
33
31
  "bin/txcatcher",
32
+ "bin/txcatcher-monitor",
34
33
  "db/migrations/001_create_transactions.rb",
35
34
  "db/migrations/002_create_addresses.rb",
36
35
  "db/migrations/003_create_deposits.rb",
36
+ "db/migrations/004_add_timestamps_to_transactions.rb",
37
+ "db/migrations/005_add_protected_flag_to_transactions.rb",
37
38
  "db/schema.rb",
38
39
  "lib/tasks/db.rake",
39
40
  "lib/txcatcher.rb",
@@ -42,20 +43,22 @@ Gem::Specification.new do |s|
42
43
  "lib/txcatcher/cleaner.rb",
43
44
  "lib/txcatcher/config.rb",
44
45
  "lib/txcatcher/initializer.rb",
46
+ "lib/txcatcher/logger.rb",
45
47
  "lib/txcatcher/models/address.rb",
46
48
  "lib/txcatcher/models/deposit.rb",
47
49
  "lib/txcatcher/models/transaction.rb",
48
50
  "lib/txcatcher/server.rb",
51
+ "lib/txcatcher/utils/crypto_unit.rb",
49
52
  "lib/txcatcher/utils/hash_string_to_sym_keys.rb",
50
53
  "spec/catcher_spec.rb",
51
54
  "spec/cleaner_spec.rb",
52
55
  "spec/config/config.yml.sample",
53
- "spec/config/txcatcher_test.db",
54
56
  "spec/fixtures/transaction.txt",
55
57
  "spec/fixtures/transaction_decoded_no_outputs.txt",
56
- "spec/models/address_spec.rb",
58
+ "spec/logger_spec.rb",
57
59
  "spec/models/transaction_spec.rb",
58
60
  "spec/spec_helper.rb",
61
+ "spec/utils/crypto_unit.rb",
59
62
  "templates/config.yml",
60
63
  "txcatcher.gemspec"
61
64
  ]
@@ -71,14 +74,20 @@ Gem::Specification.new do |s|
71
74
  s.add_runtime_dependency(%q<goliath>, [">= 0"])
72
75
  s.add_runtime_dependency(%q<sequel>, [">= 0"])
73
76
  s.add_runtime_dependency(%q<ffi-rzmq>, [">= 0"])
74
- s.add_runtime_dependency(%q<satoshi-unit>, [">= 0"])
77
+ s.add_runtime_dependency(%q<crypto-unit>, [">= 0"])
78
+ s.add_runtime_dependency(%q<sentry-raven>, [">= 0"])
79
+ s.add_runtime_dependency(%q<aws-sdk-ses>, [">= 0"])
80
+ s.add_runtime_dependency(%q<faraday>, [">= 0"])
75
81
  s.add_development_dependency(%q<bundler>, [">= 0"])
76
82
  s.add_development_dependency(%q<jeweler>, [">= 0"])
77
83
  else
78
84
  s.add_dependency(%q<goliath>, [">= 0"])
79
85
  s.add_dependency(%q<sequel>, [">= 0"])
80
86
  s.add_dependency(%q<ffi-rzmq>, [">= 0"])
81
- s.add_dependency(%q<satoshi-unit>, [">= 0"])
87
+ s.add_dependency(%q<crypto-unit>, [">= 0"])
88
+ s.add_dependency(%q<sentry-raven>, [">= 0"])
89
+ s.add_dependency(%q<aws-sdk-ses>, [">= 0"])
90
+ s.add_dependency(%q<faraday>, [">= 0"])
82
91
  s.add_dependency(%q<bundler>, [">= 0"])
83
92
  s.add_dependency(%q<jeweler>, [">= 0"])
84
93
  end
@@ -86,7 +95,10 @@ Gem::Specification.new do |s|
86
95
  s.add_dependency(%q<goliath>, [">= 0"])
87
96
  s.add_dependency(%q<sequel>, [">= 0"])
88
97
  s.add_dependency(%q<ffi-rzmq>, [">= 0"])
89
- s.add_dependency(%q<satoshi-unit>, [">= 0"])
98
+ s.add_dependency(%q<crypto-unit>, [">= 0"])
99
+ s.add_dependency(%q<sentry-raven>, [">= 0"])
100
+ s.add_dependency(%q<aws-sdk-ses>, [">= 0"])
101
+ s.add_dependency(%q<faraday>, [">= 0"])
90
102
  s.add_dependency(%q<bundler>, [">= 0"])
91
103
  s.add_dependency(%q<jeweler>, [">= 0"])
92
104
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: txcatcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.85
4
+ version: 0.1.86
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Snitko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-03 00:00:00.000000000 Z
11
+ date: 2018-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: goliath
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: aws-sdk-ses
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: faraday
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: bundler
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -112,9 +140,8 @@ description: Ccurrently, the only job of this gem is to collect all new Bitcoin/
112
140
  transactions, store them in a DB, index addresses.
113
141
  email: roman.snitko@gmail.com
114
142
  executables:
115
- - goliath.log
116
- - goliath_stdout.log
117
143
  - txcatcher
144
+ - txcatcher-monitor
118
145
  extensions: []
119
146
  extra_rdoc_files:
120
147
  - LICENSE.txt
@@ -128,9 +155,8 @@ files:
128
155
  - README.md
129
156
  - Rakefile
130
157
  - VERSION
131
- - bin/goliath.log
132
- - bin/goliath_stdout.log
133
158
  - bin/txcatcher
159
+ - bin/txcatcher-monitor
134
160
  - db/migrations/001_create_transactions.rb
135
161
  - db/migrations/002_create_addresses.rb
136
162
  - db/migrations/003_create_deposits.rb
data/bin/goliath.log DELETED
@@ -1,2 +0,0 @@
1
- [16007:INFO] 2017-09-23 23:23:59 :: Starting server on http://0.0.0.0:9498 in development mode. Watch out for stones.
2
- [16007:INFO] 2017-09-23 23:24:49 :: Stopping server...
File without changes