txcatcher 0.1.100 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1086c9abb33b98018483d2188efe2318d2c5e326a73eec1bf91056c48dce84e2
4
- data.tar.gz: 8f39e9d6aad3ed2717c36fa4e276b3aba59ee5b3248d8d1396007fd5606615ae
3
+ metadata.gz: 9bf1548d64396f39c3f5dd29ce44c08db1cf0a8b7a561621964d93157afb2736
4
+ data.tar.gz: c84ec5f6b8c02b5edc5c37bc53550079ad80ff899778959d59b7162f8bedd62b
5
5
  SHA512:
6
- metadata.gz: d282ba132fa8a3a08a4a4a11840e46a2609eea837595a4c47432697cdbb5d105fdba690acff8c5b2c442bb357cbf1618bed68916b02fecb6f37157f6e23f5ef9
7
- data.tar.gz: 35fd9704e8f5ec349a3fe1e5f3c4acc8c900fdb0c3d99590ed5c9640a24acdd0672c5bf78bdedfd3d7f724ead52ab0b225f8f0c4df95fa03e403493ba0107515
6
+ metadata.gz: c753e7883e49dbd218424f43e3edde6431bbec2a9d3817991424933c38515f27c118bfd65ac7778a725ed08a0becb6e93a6ee7330ecf0b7fa607f9c397d4f25a
7
+ data.tar.gz: 4bba3d57d20cddad92b8221984df9d8913e46cbbbda3db744529e5e4f577a8327e99b390d5c8a94ed60b3691070562d71478f41666284d20e68d36d2e89985de
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.100
1
+ 0.2.0
@@ -27,6 +27,21 @@ class BitcoinRPC
27
27
  http.request(request).body
28
28
  end
29
29
 
30
+ def get_block_transactions(block_height)
31
+ TxCatcher::LOGGER.report "--- checking transactions in block #{block_height}"
32
+ block_hash = self.getblockhash(block_height)
33
+ TxCatcher.rpc_node.getblock(block_hash)
34
+ end
35
+
36
+ def get_blocks(limit=100)
37
+ blocks = []
38
+ limit.times do |i|
39
+ height = TxCatcher.current_block_height - i
40
+ blocks << get_block_transactions(height)
41
+ end
42
+ blocks
43
+ end
44
+
30
45
  class JSONRPCError < RuntimeError
31
46
  attr_accessor :data
32
47
  def initialize(data)
@@ -44,33 +44,35 @@ module TxCatcher
44
44
 
45
45
  # Queries rpc node to check whether the transaction has been included in any of the blocks,
46
46
  # but only if current block_height is nil.
47
- def update_block_height!(limit=100,dont_save=false)
48
-
49
- # This calculates the approximate number of blocks to check.
50
- # So, for example, if transaction is less than 10 minutes old,
51
- # there's probably no reason to try and check more than 2-3 blocks back.
52
- # However, to make absolute sure, we always bump up this number for 10 blocks.
53
- # Over larger periods of time, the avg block per minute value should even out, so
54
- # it's probably going to be fine either way.
55
- created_minutes_ago = ((self.created_at - Time.now).to_i/60)
56
- blocks_to_check = (created_minutes_ago / 10).abs + 10
47
+ def update_block_height!(dont_save: false, blocks: nil)
57
48
  return self.block_height if self.block_height
58
- blocks_to_check = limit if blocks_to_check > limit
49
+ blocks = TxCatcher.rpc_node.get_blocks(blocks_to_check_for_inclusion_if_unconfirmed) unless blocks
59
50
 
60
- i = 0
61
- while i <= blocks_to_check
62
- block_hash = TxCatcher.rpc_node.getblockhash(TxCatcher.current_block_height - i)
63
- block = TxCatcher.rpc_node.getblock(block_hash)
64
- i += 1
65
- LOGGER.report "--- checking block #{TxCatcher.current_block_height - i} for tx #{self.txid}"
51
+ for block in blocks do
66
52
  if block["tx"] && block["tx"].include?(self.txid)
67
53
  LOGGER.report "tx #{self.txid} block height updated to #{block["height"]}"
68
54
  self.update(block_height: block["height"]) if !dont_save
69
55
  return block["height"].to_i
56
+ else
57
+ return nil
70
58
  end
71
59
  end
72
60
  end
73
61
 
62
+ # This calculates the approximate number of blocks to check.
63
+ # So, for example, if transaction is less than 10 minutes old,
64
+ # there's probably no reason to try and check more than 2-3 blocks back.
65
+ # However, to make absolute sure, we always bump up this number by 10 blocks.
66
+ # Over larger periods of time, the avg block per minute value should even out, so
67
+ # it's probably going to be fine either way.
68
+ def blocks_to_check_for_inclusion_if_unconfirmed(limit=100)
69
+ return false if self.block_height
70
+ created_minutes_ago = ((self.created_at - Time.now).to_i/60)
71
+ blocks_to_check = (created_minutes_ago / 10).abs + 10
72
+ blocks_to_check = limit if blocks_to_check > limit
73
+ blocks_to_check
74
+ end
75
+
74
76
  private
75
77
 
76
78
  def parse_transaction
@@ -1,3 +1,4 @@
1
+ require 'ruby-prof'
1
2
  module TxCatcher
2
3
 
3
4
  class Server < Goliath::API
@@ -9,9 +10,12 @@ module TxCatcher
9
10
  begin
10
11
  return route_for(uri)
11
12
  rescue BitcoinRPC::JSONRPCError => e
13
+ puts e.to_s
14
+ puts e.backtrace.join("\n")
12
15
  return [400, {}, { error: e.data }.to_json]
13
16
  rescue Exception => e
14
- p e.backtrace
17
+ puts e.to_s
18
+ puts e.backtrace.join("\n")
15
19
  return [500, {}, { error: e.to_s }.to_json]
16
20
  end
17
21
  end
@@ -72,6 +76,7 @@ module TxCatcher
72
76
  newly_confirmed_txs_to_update = []
73
77
 
74
78
  transactions = model.deposits.map { |d| d.transaction }
79
+ transactions.sort! { |t1,t2| t2.created_at <=> t1.created_at }
75
80
  utxos = transactions.map do |t|
76
81
  outs = t.tx_hash["vout"].select { |out| out["scriptPubKey"]["addresses"] == [addr] }
77
82
  outs.map! do |out|
@@ -84,8 +89,10 @@ module TxCatcher
84
89
  outs
85
90
  end.flatten
86
91
 
92
+ blocks = TxCatcher.rpc_node.get_blocks(unconfirmed_txs_to_update.first.blocks_to_check_for_inclusion_if_unconfirmed)
93
+
87
94
  unconfirmed_txs_to_update = unconfirmed_txs_to_update.map do |t|
88
- tx_block_height = t.update_block_height!(100,:dont_save)
95
+ tx_block_height = t.update_block_height!(dont_save: true, blocks: blocks)
89
96
  if tx_block_height && tx_block_height > 0
90
97
  newly_confirmed_txs_to_update << t
91
98
  nil
@@ -27,8 +27,8 @@ RSpec.describe TxCatcher::Transaction do
27
27
  end
28
28
 
29
29
  it "updates block height by making manual requests to RPC and searching if tx is included in one of the previous blocks" do
30
- expect(TxCatcher.rpc_node).to receive(:getblockhash).and_return("blockhash123")
31
- expect(TxCatcher.rpc_node).to receive(:getblock).and_return({ "height" => "123", "tx" => [@transaction.txid], "hash" => "blockhash123"})
30
+ expect(TxCatcher.rpc_node).to receive(:getblockhash).exactly(10).times.and_return("blockhash123")
31
+ expect(TxCatcher.rpc_node).to receive(:getblock).exactly(10).times.and_return({ "height" => "123", "tx" => [@transaction.txid], "hash" => "blockhash123"})
32
32
  @transaction.update_block_height!
33
33
  expect(@transaction.block_height).to eq(123)
34
34
  end
data/txcatcher.gemspec CHANGED
@@ -2,11 +2,11 @@
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.100 ruby lib
5
+ # stub: txcatcher 0.2.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "txcatcher".freeze
9
- s.version = "0.1.100"
9
+ s.version = "0.2.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: txcatcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.100
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Snitko