cryptocoin_payable 1.2.0 → 1.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7b465403012fd6c2c62f916507601f6a461ec9f6
4
- data.tar.gz: 660aabdd9e68754853025ca889b5a503b01b0a12
2
+ SHA256:
3
+ metadata.gz: 69a13a8a0c2157e87c41dde92831b8ad336aab77a9d58314adfddedf4808509d
4
+ data.tar.gz: 216d48f0578f487fd0420469d7d0a6214b7dc205aae65aab92d21f837fafe723
5
5
  SHA512:
6
- metadata.gz: 4616fb4173f7ffbfd1893cbc6546b5a69bdd1ee823f9af4b3a8497fa9fd4e987d4b350e4fd427a7c236197bd2f6c723058d687f20bf9b770ef44f1703cda420d
7
- data.tar.gz: 1903bffd04558bf5b732547e4be3492c9198b587fe068ba701c5300393b48faa86919238b3973755133dfdca8dfcdd46fe81a04c4f8bf18ffe05b677774744f2
6
+ metadata.gz: f3ceadd2dd62f11a419119583a0fbeeaee72418c9d7c318caba1542809a91dbc06f671f6eed7afc1136cc3556ddc5c535df475b501fa741cd03d2270c493ad81
7
+ data.tar.gz: 0b340f0086b3411eef2df4f434bc46b12166969ddea73741227382c64d78cc8e88fbaeee9843a26eed3cbf64f07821cd3b658bb4cc628a7262616c7ede99e122
data/README.md CHANGED
@@ -48,7 +48,7 @@ And then execute:
48
48
 
49
49
  $ bundle exec rake db:migrate
50
50
 
51
- $ populate coin_payable.rb (see below)
51
+ $ populate cryptocoin_payable.rb (see below)
52
52
 
53
53
  $ bundle exec rake cryptocoin_payable:process_prices (see below)
54
54
 
@@ -65,7 +65,7 @@ And then execute:
65
65
 
66
66
  ### Configuration
67
67
 
68
- config/initializers/coin_payable.rb
68
+ config/initializers/cryptocoin_payable.rb
69
69
 
70
70
  CryptocoinPayable.configure do |config|
71
71
  # config.currency = :usd
@@ -26,12 +26,15 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency 'database_cleaner', '~> 1.7'
27
27
  spec.add_development_dependency 'rails', '>= 4.0.0'
28
28
  spec.add_development_dependency 'rake', '~> 12.3'
29
+ spec.add_development_dependency 'rspec-benchmark', '~> 0.4'
29
30
  spec.add_development_dependency 'rspec-rails', '~> 3.7'
31
+ spec.add_development_dependency 'rspec-retry', '~> 0.6'
30
32
  spec.add_development_dependency 'rubocop', '~> 0.59'
31
33
  spec.add_development_dependency 'sqlite3', '~> 1.3'
32
34
  spec.add_development_dependency 'vcr', '~> 4.0'
33
35
  spec.add_development_dependency 'webmock', '~> 3.4'
34
36
 
37
+ spec.add_dependency 'activerecord-import', '~> 0.27'
35
38
  spec.add_dependency 'cash-addr', '~> 0.2'
36
39
  spec.add_dependency 'eth', '0.4.8'
37
40
  spec.add_dependency 'money-tree', '0.10.0'
@@ -22,11 +22,11 @@ end
22
22
  Given(/^a payment is made for (\d+) percent$/) do |percentage|
23
23
  CryptocoinPayable::Adapters::Bitcoin.any_instance.stub(:fetch_transactions).and_return(
24
24
  [{
25
- tx_hash: SecureRandom.uuid,
25
+ transaction_hash: SecureRandom.uuid,
26
26
  block_hash: '00000000000000606aa74093ed91d657192a3772732ee4d99a7b7be8075eafa2',
27
27
  block_time: DateTime.iso8601('2017-12-26T21:38:44.000+00:00'),
28
- estimated_tx_time: DateTime.iso8601('2017-12-26T21:30:19.858+00:00'),
29
- estimated_tx_value: @coin_amount_due * (percentage.to_f / 100.0),
28
+ estimated_time: DateTime.iso8601('2017-12-26T21:30:19.858+00:00'),
29
+ estimated_value: @coin_amount_due * (percentage.to_f / 100.0),
30
30
  confirmations: 1
31
31
  }]
32
32
  )
@@ -4,6 +4,8 @@ ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '../../../spec/dummy'
4
4
  require 'cucumber/rails'
5
5
  require 'cucumber/rspec/doubles'
6
6
 
7
+ # ActiveRecord::Base.logger = Logger.new(STDOUT) if defined?(ActiveRecord::Base)
8
+
7
9
  # Remove/comment out the lines below if your app doesn't have a database.
8
10
  # For some databases (like MongoDB and CouchDB) you may need to use :truncation instead.
9
11
  begin
@@ -16,14 +16,14 @@ module CryptocoinPayable
16
16
  # Queries an API like etherscan.io and returns a list of transactions
17
17
  # which conform to the following shape:
18
18
  # {
19
- # tx_hash: string,
19
+ # transaction_hash: string,
20
20
  # block_hash: string,
21
21
  # block_time: nil | string,
22
- # estimated_tx_time: nil | string,
23
- # estimated_tx_value: integer,
22
+ # estimated_time: nil | string,
23
+ # estimated_value: integer,
24
24
  # confirmations: integer,
25
25
  # }
26
- # `block_time` and `estimated_tx_time` are optional strings conforming to
26
+ # `block_time` and `estimated_time` are optional strings conforming to
27
27
  # date format ISO 8601.
28
28
  #
29
29
  # Can optionally raise ApiLimitedReached if needed.
@@ -52,11 +52,11 @@ module CryptocoinPayable
52
52
 
53
53
  def convert_block_explorer_transactions(transaction, address)
54
54
  {
55
- tx_hash: transaction['txid'],
55
+ transaction_hash: transaction['txid'],
56
56
  block_hash: transaction['blockhash'],
57
57
  block_time: parse_timestamp(transaction['blocktime']),
58
- estimated_tx_time: parse_timestamp(transaction['time']),
59
- estimated_tx_value: parse_total_tx_value_block_explorer(transaction['vout'], address),
58
+ estimated_time: parse_timestamp(transaction['time']),
59
+ estimated_value: parse_total_tx_value_block_explorer(transaction['vout'], address),
60
60
  confirmations: transaction['confirmations']
61
61
  }
62
62
  end
@@ -83,11 +83,11 @@ module CryptocoinPayable
83
83
 
84
84
  def convert_block_cypher_transactions(transaction, address)
85
85
  {
86
- tx_hash: transaction['hash'],
86
+ transaction_hash: transaction['hash'],
87
87
  block_hash: transaction['block_hash'],
88
88
  block_time: parse_time(transaction['confirmed']),
89
- estimated_tx_time: parse_time(transaction['received']),
90
- estimated_tx_value: parse_total_tx_value_block_cypher(transaction['outputs'], address),
89
+ estimated_time: parse_time(transaction['received']),
90
+ estimated_value: parse_total_tx_value_block_cypher(transaction['outputs'], address),
91
91
  confirmations: transaction['confirmations'].to_i
92
92
  }
93
93
  end
@@ -63,11 +63,11 @@ module CryptocoinPayable
63
63
  # }
64
64
  def convert_transactions(transaction, _address)
65
65
  {
66
- tx_hash: transaction['hash'],
66
+ transaction_hash: transaction['hash'],
67
67
  block_hash: transaction['block_hash'],
68
68
  block_time: nil, # Not supported
69
- estimated_tx_time: parse_timestamp(transaction['timeStamp']),
70
- estimated_tx_value: transaction['value'].to_i, # Units here are 'Wei'
69
+ estimated_time: parse_timestamp(transaction['timeStamp']),
70
+ estimated_value: transaction['value'].to_i, # Units here are 'Wei'
71
71
  confirmations: transaction['confirmations'].to_i
72
72
  }
73
73
  end
@@ -4,20 +4,7 @@ require 'state_machine'
4
4
  module CryptocoinPayable
5
5
  class CoinPayment < ActiveRecord::Base
6
6
  belongs_to :payable, polymorphic: true
7
-
8
- has_many :transactions, class_name: 'CryptocoinPayable::CoinPaymentTransaction' do
9
- def create_from_tx_data!(tx_data, coin_conversion)
10
- create!(
11
- estimated_value: tx_data[:estimated_tx_value],
12
- transaction_hash: tx_data[:tx_hash],
13
- block_hash: tx_data[:block_hash],
14
- block_time: tx_data[:block_time],
15
- estimated_time: tx_data[:estimated_tx_time],
16
- coin_conversion: coin_conversion,
17
- confirmations: tx_data[:confirmations]
18
- )
19
- end
20
- end
7
+ has_many :transactions, class_name: 'CryptocoinPayable::CoinPaymentTransaction'
21
8
 
22
9
  validates :reason, presence: true
23
10
  validates :price, presence: true
@@ -93,8 +80,18 @@ module CryptocoinPayable
93
80
  end
94
81
 
95
82
  def calculate_coin_amount_due
96
- rate = CurrencyConversion.where(coin_type: coin_type).last.price
97
- adapter.convert_main_to_subunit(currency_amount_due / rate.to_f).ceil
83
+ adapter.convert_main_to_subunit(currency_amount_due / coin_conversion.to_f).ceil
84
+ end
85
+
86
+ def coin_conversion
87
+ @coin_conversion ||= CurrencyConversion.where(coin_type: coin_type).last.price
88
+ end
89
+
90
+ def update_coin_amount_due(rate: coin_conversion)
91
+ update!(
92
+ coin_amount_due: calculate_coin_amount_due,
93
+ coin_conversion: rate
94
+ )
98
95
  end
99
96
 
100
97
  def transactions_confirmed?
@@ -112,7 +109,7 @@ module CryptocoinPayable
112
109
  def populate_currency_and_amount_due
113
110
  self.currency ||= CryptocoinPayable.configuration.currency
114
111
  self.coin_amount_due = calculate_coin_amount_due
115
- self.coin_conversion = CurrencyConversion.where(coin_type: coin_type).last.price
112
+ self.coin_conversion = coin_conversion
116
113
  end
117
114
 
118
115
  def populate_address
@@ -1,3 +1,5 @@
1
+ require 'activerecord-import'
2
+
1
3
  module CryptocoinPayable
2
4
  class PaymentProcessor
3
5
  def self.perform
@@ -5,22 +7,7 @@ module CryptocoinPayable
5
7
  end
6
8
 
7
9
  def self.update_transactions_for(payment)
8
- transactions = Adapters.for(payment.coin_type).fetch_transactions(payment.address)
9
-
10
- transactions.each do |tx|
11
- tx.symbolize_keys!
12
-
13
- transaction = payment.transactions.find_by_transaction_hash(tx[:tx_hash])
14
- if transaction
15
- transaction.update(confirmations: tx[:confirmations])
16
- else
17
- payment.transactions.create_from_tx_data!(tx, payment.coin_conversion)
18
- payment.update(
19
- coin_amount_due: payment.calculate_coin_amount_due,
20
- coin_conversion: CurrencyConversion.where(coin_type: payment.coin_type).last.price
21
- )
22
- end
23
- end
10
+ new.update_transactions_for(payment)
24
11
  end
25
12
 
26
13
  def perform
@@ -32,7 +19,7 @@ module CryptocoinPayable
32
19
  next if payment.confirmed?
33
20
 
34
21
  begin
35
- self.class.update_transactions_for(payment)
22
+ update_transactions_for(payment)
36
23
  rescue StandardError => error
37
24
  STDERR.puts 'PaymentProcessor: Unknown error encountered, skipping transaction'
38
25
  STDERR.puts error
@@ -48,7 +35,51 @@ module CryptocoinPayable
48
35
  end
49
36
  end
50
37
 
51
- protected
38
+ def update_transactions_for(payment)
39
+ transactions = Adapters.for(payment.coin_type).fetch_transactions(payment.address)
40
+
41
+ payment.transaction do
42
+ if ActiveRecord::Base.connection.supports_on_duplicate_key_update?
43
+ update_via_bulk_insert(payment, transactions)
44
+ else
45
+ update_via_many_insert(payment, transactions)
46
+ end
47
+ end
48
+
49
+ transactions
50
+ end
51
+
52
+ private
53
+
54
+ def update_via_bulk_insert(payment, transactions)
55
+ transactions.each do |t|
56
+ t[:coin_conversion] = payment.coin_conversion
57
+ t[:coin_payment_id] = payment.id
58
+ end
59
+
60
+ CoinPaymentTransaction.import(
61
+ transactions,
62
+ on_duplicate_key_update: {
63
+ conflict_target: [:transaction_hash],
64
+ columns: [:coin_conversion]
65
+ }
66
+ )
67
+ payment.reload
68
+ payment.update_coin_amount_due
69
+ end
70
+
71
+ def update_via_many_insert(payment, transactions)
72
+ transactions.each do |tx|
73
+ transaction = payment.transactions.find_by_transaction_hash(tx[:transaction_hash])
74
+ if transaction
75
+ transaction.update(confirmations: tx[:confirmations])
76
+ else
77
+ tx[:coin_conversion] = payment.coin_conversion
78
+ payment.transactions.create!(tx)
79
+ payment.update_coin_amount_due
80
+ end
81
+ end
82
+ end
52
83
 
53
84
  def update_payment_state(payment)
54
85
  if payment.currency_amount_paid >= payment.price
@@ -25,10 +25,7 @@ module CryptocoinPayable
25
25
  # Loop through all unpaid payments and update them with the new price if
26
26
  # it has been 30 mins since they have been updated.
27
27
  CoinPayment.unpaid.stale.find_each do |payment|
28
- payment.update!(
29
- coin_amount_due: payment.calculate_coin_amount_due,
30
- coin_conversion: rates[payment.coin_type.to_sym].price
31
- )
28
+ payment.update_coin_amount_due(coin_conversion: rates[payment.coin_type.to_sym].price)
32
29
  end
33
30
  end
34
31
 
@@ -1,3 +1,3 @@
1
1
  module CryptocoinPayable
2
- VERSION = '1.2.0'.freeze
2
+ VERSION = '1.3.0'.freeze
3
3
  end
@@ -2,7 +2,7 @@ class CreateCoinPaymentTransactions < ActiveRecord::Migration[5.1]
2
2
  def change
3
3
  create_table :coin_payment_transactions do |t|
4
4
  t.decimal :estimated_value, precision: 24, scale: 0
5
- t.string :transaction_hash
5
+ t.string :transaction_hash, index: { unique: true }
6
6
  t.string :block_hash
7
7
  t.datetime :block_time
8
8
  t.datetime :estimated_time
@@ -8,11 +8,11 @@ describe CryptocoinPayable::Adapters::BitcoinCash, :vcr do
8
8
  expect(response).to eq(
9
9
  [
10
10
  {
11
- tx_hash: '10d9d3927a21d90c573a5fbbb347f409af37219ceb93f7475d6c4cca4231d29f',
11
+ transaction_hash: '10d9d3927a21d90c573a5fbbb347f409af37219ceb93f7475d6c4cca4231d29f',
12
12
  block_hash: '0000000000000000015493ab50fde669130f9b64f0918031a5b6dcc44f14698f',
13
13
  block_time: DateTime.iso8601('2018-10-12T07:28:21.000000000+00:00'),
14
- estimated_tx_time: DateTime.iso8601('2018-10-12T07:28:21.000000000+00:00'),
15
- estimated_tx_value: 4_128_450,
14
+ estimated_time: DateTime.iso8601('2018-10-12T07:28:21.000000000+00:00'),
15
+ estimated_value: 4_128_450,
16
16
  confirmations: 2
17
17
  }
18
18
  ]
@@ -6,19 +6,19 @@ describe CryptocoinPayable::Adapters::Bitcoin, :vcr do
6
6
  expect(response).to match_array(
7
7
  [
8
8
  {
9
- tx_hash: '5bdeaf7829148d7e0e1e7b5233512a2c5ae54ef7ccbc8e68b2f85b7e49c917a0',
9
+ transaction_hash: '5bdeaf7829148d7e0e1e7b5233512a2c5ae54ef7ccbc8e68b2f85b7e49c917a0',
10
10
  block_hash: '0000000000000000048e8ea3fdd2c3a59ddcbcf7575f82cb96ce9fd17da9f2f4',
11
11
  block_time: DateTime.iso8601('2016-09-13T15:41:00.000000000+00:00'),
12
- estimated_tx_time: be_within(1.day).of(DateTime.iso8601('2016-09-13T15:41:00.000000000+00:00')),
13
- estimated_tx_value: 499_000_000,
12
+ estimated_time: be_within(1.day).of(DateTime.iso8601('2016-09-13T15:41:00.000000000+00:00')),
13
+ estimated_value: 499_000_000,
14
14
  confirmations: 116_077
15
15
  },
16
16
  {
17
- tx_hash: 'e7bcdb13d9c903973bd8a740054d4c056a559bae67d4e8f6d0a42b4bab552623',
17
+ transaction_hash: 'e7bcdb13d9c903973bd8a740054d4c056a559bae67d4e8f6d0a42b4bab552623',
18
18
  block_hash: '000000000000000001af27feb303ad97af81a5882157f166781784c639f8e896',
19
19
  block_time: DateTime.iso8601('2016-09-13T15:22:42.000000000+00:00'),
20
- estimated_tx_time: be_within(1.day).of(DateTime.iso8601('2016-09-13T15:22:42.000000000+00:00')),
21
- estimated_tx_value: 1_000_000,
20
+ estimated_time: be_within(1.day).of(DateTime.iso8601('2016-09-13T15:22:42.000000000+00:00')),
21
+ estimated_value: 1_000_000,
22
22
  confirmations: 116_080
23
23
  }
24
24
  ]
@@ -6,35 +6,35 @@ describe CryptocoinPayable::Adapters::Ethereum, :vcr do
6
6
  expect(response).to match_array(
7
7
  [
8
8
  {
9
- tx_hash: '0xa88b799514e9621962e3d0de25e7e0bc7a123e33085f322c7acdb99cc2585c6d',
9
+ transaction_hash: '0xa88b799514e9621962e3d0de25e7e0bc7a123e33085f322c7acdb99cc2585c6d',
10
10
  block_hash: '0x752c50e426f65820f5bf6fd49acbb08d79464f8e7e8ea5b77e2299b69fd6398b',
11
11
  block_time: nil,
12
- estimated_tx_time: be_within(1.day).of(DateTime.iso8601('2018-07-05T12:58:33.000000000+07:00')),
13
- estimated_tx_value: 33_753_640_000_000_000,
12
+ estimated_time: be_within(1.day).of(DateTime.iso8601('2018-07-05T12:58:33.000000000+07:00')),
13
+ estimated_value: 33_753_640_000_000_000,
14
14
  confirmations: 569_771
15
15
  },
16
16
  {
17
- tx_hash: '0xb325a8cf241f332bca92c7f715987e4d34be9a6b3bb78d2425c83086b4aced26',
17
+ transaction_hash: '0xb325a8cf241f332bca92c7f715987e4d34be9a6b3bb78d2425c83086b4aced26',
18
18
  block_hash: '0x1c2b73a16fd8c4d25feeccaa2f0bf5c82b8f415f1beaf4d34aaf870daf89689d',
19
19
  block_time: nil,
20
- estimated_tx_time: be_within(1.day).of(DateTime.iso8601('2018-07-05T13:35:07.000000000+07:00')),
21
- estimated_tx_value: 2_190_144_444_444_444,
20
+ estimated_time: be_within(1.day).of(DateTime.iso8601('2018-07-05T13:35:07.000000000+07:00')),
21
+ estimated_value: 2_190_144_444_444_444,
22
22
  confirmations: 569_629
23
23
  },
24
24
  {
25
- tx_hash: '0xcd874917be5ad177e7ebd88b5c4a7d4283796e00e43345da5b63fb4f78130b37',
25
+ transaction_hash: '0xcd874917be5ad177e7ebd88b5c4a7d4283796e00e43345da5b63fb4f78130b37',
26
26
  block_hash: '0x4ce71d11146445f123680ea9beba7db968b04dc675caddf60248c9d9d6f5739e',
27
27
  block_time: nil,
28
- estimated_tx_time: be_within(1.day).of(DateTime.iso8601('2018-07-05T13:55:53.000000000+07:00')),
29
- estimated_tx_value: 1_007_518_888_888_888,
28
+ estimated_time: be_within(1.day).of(DateTime.iso8601('2018-07-05T13:55:53.000000000+07:00')),
29
+ estimated_value: 1_007_518_888_888_888,
30
30
  confirmations: 569_549
31
31
  },
32
32
  {
33
- tx_hash: '0x799ec2aaafbddbc2e746334f96f59f6127dec62e5693480576db351aaf840bfb',
33
+ transaction_hash: '0x799ec2aaafbddbc2e746334f96f59f6127dec62e5693480576db351aaf840bfb',
34
34
  block_hash: '0xc1361b19b2266e2259ac433b9e18b4fbc81339304988bbc62dd93aa24fac6449',
35
35
  block_time: nil,
36
- estimated_tx_time: be_within(1.day).of(DateTime.iso8601('2018-08-26T16:05:44.000000000+07:00')),
37
- estimated_tx_value: 15_678_420_000_000_000,
36
+ estimated_time: be_within(1.day).of(DateTime.iso8601('2018-08-26T16:05:44.000000000+07:00')),
37
+ estimated_value: 15_678_420_000_000_000,
38
38
  confirmations: 261_969
39
39
  }
40
40
  ]
@@ -0,0 +1,50 @@
1
+ require 'active_record'
2
+ require 'database_cleaner'
3
+ require 'cryptocoin_payable/orm/activerecord'
4
+
5
+ describe CryptocoinPayable::PaymentProcessor do
6
+ def build_fake_transactions_data
7
+ transactions = []
8
+ 300.times do
9
+ transactions << {
10
+ transaction_hash: '5bdeaf7829148d7e0e1e7b5233512a2c5ae54ef7ccbc8e68b2f85b7e49c917a0',
11
+ block_hash: '0000000000000000048e8ea3fdd2c3a59ddcbcf7575f82cb96ce9fd17da9f2f4',
12
+ block_time: DateTime.iso8601('2016-09-13T15:41:00.000000000+00:00'),
13
+ estimated_time: DateTime.iso8601('2016-09-13T15:41:00.000000000+00:00'),
14
+ estimated_value: 499_000_000,
15
+ confirmations: 116_077
16
+ }
17
+ end
18
+ transactions
19
+ end
20
+
21
+ context 'when testing performance of database interaction' do
22
+ before(:all) do
23
+ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'spec/dummy/db/test.sqlite3')
24
+ DatabaseCleaner.strategy = :truncation
25
+ GC.disable
26
+ end
27
+
28
+ after(:all) do
29
+ GC.enable
30
+ end
31
+
32
+ before do
33
+ DatabaseCleaner.clean
34
+ CryptocoinPayable::CurrencyConversion.create!(coin_type: :btc, currency: 1, price: 1)
35
+ adapter = CryptocoinPayable::Adapters.bitcoin_adapter
36
+ allow(adapter).to receive(:fetch_transactions) { build_fake_transactions_data }
37
+ end
38
+
39
+ after do
40
+ DatabaseCleaner.clean
41
+ end
42
+
43
+ it 'should insert 300 transactions in under 300ms', retry: 3 do
44
+ payment = CryptocoinPayable::CoinPayment.create!(reason: 'test', price: 1, coin_type: :btc)
45
+ payment.update(address: '3HR9xYD7MybbE7JLVTjwijYse48BtfEKni')
46
+
47
+ expect { subject.update_transactions_for(payment) }.to perform_under(300).ms
48
+ end
49
+ end
50
+ end
Binary file
@@ -2,7 +2,7 @@ class CreateCoinPaymentTransactions < ActiveRecord::Migration[5.1]
2
2
  def change
3
3
  create_table :coin_payment_transactions do |t|
4
4
  t.decimal :estimated_value, precision: 24, scale: 0
5
- t.string :transaction_hash
5
+ t.string :transaction_hash, index: { unique: true }
6
6
  t.string :block_hash
7
7
  t.datetime :block_time
8
8
  t.datetime :estimated_time
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 20_171_227_225_134) do
13
+ ActiveRecord::Schema.define(version: 20_181_015_141_952) do
14
14
  create_table 'coin_payment_transactions', force: :cascade do |t|
15
15
  t.decimal 'estimated_value', precision: 24
16
16
  t.string 'transaction_hash'
@@ -21,6 +21,7 @@ ActiveRecord::Schema.define(version: 20_171_227_225_134) do
21
21
  t.decimal 'coin_conversion', precision: 24
22
22
  t.integer 'confirmations', default: 0
23
23
  t.index ['coin_payment_id'], name: 'index_coin_payment_transactions_on_coin_payment_id'
24
+ t.index ['transaction_hash'], name: 'index_coin_payment_transactions_on_transaction_hash', unique: true
24
25
  end
25
26
 
26
27
  create_table 'coin_payments', force: :cascade do |t|
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,10 @@
1
1
  require 'vcr'
2
2
  require 'webmock/rspec'
3
3
  require 'active_support/time'
4
+ require 'rspec-benchmark'
5
+ require 'rspec/retry'
6
+
7
+ # ActiveRecord::Base.logger = Logger.new(STDOUT) if defined?(ActiveRecord::Base)
4
8
 
5
9
  VCR.configure do |config|
6
10
  config.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
@@ -59,6 +63,8 @@ RSpec.configure do |config|
59
63
  end
60
64
  end
61
65
 
66
+ config.include RSpec::Benchmark::Matchers
67
+
62
68
  # The settings below are suggested to provide a good initial experience
63
69
  # with RSpec, but feel free to customize to your heart's content.
64
70
  # # This allows you to limit a spec run to individual examples or groups
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cryptocoin_payable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Salis
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-10-15 00:00:00.000000000 Z
12
+ date: 2018-10-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -95,6 +95,20 @@ dependencies:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
97
  version: '12.3'
98
+ - !ruby/object:Gem::Dependency
99
+ name: rspec-benchmark
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '0.4'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '0.4'
98
112
  - !ruby/object:Gem::Dependency
99
113
  name: rspec-rails
100
114
  requirement: !ruby/object:Gem::Requirement
@@ -109,6 +123,20 @@ dependencies:
109
123
  - - "~>"
110
124
  - !ruby/object:Gem::Version
111
125
  version: '3.7'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rspec-retry
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: '0.6'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '0.6'
112
140
  - !ruby/object:Gem::Dependency
113
141
  name: rubocop
114
142
  requirement: !ruby/object:Gem::Requirement
@@ -165,6 +193,20 @@ dependencies:
165
193
  - - "~>"
166
194
  - !ruby/object:Gem::Version
167
195
  version: '3.4'
196
+ - !ruby/object:Gem::Dependency
197
+ name: activerecord-import
198
+ requirement: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - "~>"
201
+ - !ruby/object:Gem::Version
202
+ version: '0.27'
203
+ type: :runtime
204
+ prerelease: false
205
+ version_requirements: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - "~>"
208
+ - !ruby/object:Gem::Version
209
+ version: '0.27'
168
210
  - !ruby/object:Gem::Dependency
169
211
  name: cash-addr
170
212
  requirement: !ruby/object:Gem::Requirement
@@ -276,6 +318,7 @@ files:
276
318
  - spec/acceptance/adapters/bitcoin_cash_spec.rb
277
319
  - spec/acceptance/adapters/bitcoin_spec.rb
278
320
  - spec/acceptance/adapters/ethereum_spec.rb
321
+ - spec/acceptance/commands/payment_processor_spec.rb
279
322
  - spec/dummy/README.rdoc
280
323
  - spec/dummy/Rakefile
281
324
  - spec/dummy/app/assets/images/.keep
@@ -314,8 +357,8 @@ files:
314
357
  - spec/dummy/db/development.sqlite3
315
358
  - spec/dummy/db/migrate/20140510023211_create_widgets.rb
316
359
  - spec/dummy/db/migrate/20171227225132_create_coin_payments.rb
317
- - spec/dummy/db/migrate/20171227225133_create_coin_payment_transactions.rb
318
360
  - spec/dummy/db/migrate/20171227225134_create_currency_conversions.rb
361
+ - spec/dummy/db/migrate/20181015141952_create_coin_payment_transactions.rb
319
362
  - spec/dummy/db/schema.rb
320
363
  - spec/dummy/lib/assets/.keep
321
364
  - spec/dummy/log/.keep
@@ -355,7 +398,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
355
398
  version: 1.3.6
356
399
  requirements: []
357
400
  rubyforge_project:
358
- rubygems_version: 2.6.12
401
+ rubygems_version: 2.7.7
359
402
  signing_key:
360
403
  specification_version: 4
361
404
  summary: Cryptocurrency payment processor
@@ -372,6 +415,7 @@ test_files:
372
415
  - spec/acceptance/adapters/bitcoin_cash_spec.rb
373
416
  - spec/acceptance/adapters/bitcoin_spec.rb
374
417
  - spec/acceptance/adapters/ethereum_spec.rb
418
+ - spec/acceptance/commands/payment_processor_spec.rb
375
419
  - spec/dummy/README.rdoc
376
420
  - spec/dummy/Rakefile
377
421
  - spec/dummy/app/assets/images/.keep
@@ -410,8 +454,8 @@ test_files:
410
454
  - spec/dummy/db/development.sqlite3
411
455
  - spec/dummy/db/migrate/20140510023211_create_widgets.rb
412
456
  - spec/dummy/db/migrate/20171227225132_create_coin_payments.rb
413
- - spec/dummy/db/migrate/20171227225133_create_coin_payment_transactions.rb
414
457
  - spec/dummy/db/migrate/20171227225134_create_currency_conversions.rb
458
+ - spec/dummy/db/migrate/20181015141952_create_coin_payment_transactions.rb
415
459
  - spec/dummy/db/schema.rb
416
460
  - spec/dummy/lib/assets/.keep
417
461
  - spec/dummy/log/.keep