Class: BitcoinRPC

Inherits:
Object
  • Object
show all
Defined in:
lib/txcatcher/bitcoin_rpc.rb

Defined Under Namespace

Classes: JSONRPCError, NoTxIndexErorr

Instance Method Summary collapse

Constructor Details

#initialize(service_url) ⇒ BitcoinRPC

Returns a new instance of BitcoinRPC.



12
13
14
# File 'lib/txcatcher/bitcoin_rpc.rb', line 12

def initialize(service_url)
  @uri = URI.parse(service_url)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object

Raises:



33
34
35
36
37
38
# File 'lib/txcatcher/bitcoin_rpc.rb', line 33

def method_missing(name, *args)
  post_body = { 'method' => name, 'params' => args, 'id' => 'jsonrpc' }.to_json
  resp = JSON.parse( http_post_request(post_body) )
  raise JSONRPCError.new(resp['error'].merge({ "method" => name.to_s })) if resp['error']
  resp['result']
end

Instance Method Details

#get_block_transactions(block_height) ⇒ Object



49
50
51
52
# File 'lib/txcatcher/bitcoin_rpc.rb', line 49

def get_block_transactions(block_height)
  block_hash = self.getblockhash(block_height)
  TxCatcher.rpc_node.getblock(block_hash)
end

#get_blocks(limit = TxCatcher::Config[:max_blocks_in_memory]) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/txcatcher/bitcoin_rpc.rb', line 54

def get_blocks(limit=TxCatcher::Config[:max_blocks_in_memory])
  # We cache blocks we get from RPC to avoid repetetive requests
  # which are very slow.
  @blocks ||= {}

  blocks_removed = []
  @blocks.delete_if do |height,hash|
    if height < TxCatcher.current_block_height-TxCatcher::Config[:max_blocks_in_memory]
      blocks_removed << height
      true
    end
  end
  TxCatcher::LOGGER.report(
    "--- removing blocks\n#{blocks_removed.join(", ")}\nfrom cache, they're below the config " +
    "setting of #{TxCatcher::Config[:max_blocks_in_memory]}"
  ) unless blocks_removed.empty?

  blocks_cached = []
  limit.times do |i|
    height = TxCatcher.current_block_height - i
    unless @blocks[height]
      blocks_cached << height
      @blocks[height] = get_block_transactions(height)
    end
  end
  TxCatcher::LOGGER.report(
    "--- loading (from RPC) and caching transactions in blocks " +
    blocks_cached.join(", ")
  ) unless blocks_cached.empty?
  @blocks
end

#http_post_request(post_body) ⇒ Object



40
41
42
43
44
45
46
47
# File 'lib/txcatcher/bitcoin_rpc.rb', line 40

def http_post_request(post_body)
  http    = Net::HTTP.new(@uri.host, @uri.port)
  request = Net::HTTP::Post.new(@uri.request_uri)
  request.basic_auth @uri.user, @uri.password
  request.content_type = 'application/json'
  request.body = post_body
  http.request(request).body
end

#txindex_enabled?Boolean

Returns:

  • (Boolean)


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/txcatcher/bitcoin_rpc.rb', line 16

def txindex_enabled?
  return @tx_index_enabled unless @tx_index_enabled.nil?
  begin
    txid = self.get_block_transactions(self.getblockcount-1000)["tx"].first
    self.getrawtransaction(txid, 1)
    TxCatcher::LOGGER.report "Pruning is off, -txindex enabled, can perform RPC requests to check block_height for transactions, that's much more reliable!"
    return @tx_index_enabled = true
  rescue BitcoinRPC::JSONRPCError => e
    if e.message.include?("pruned data") || e.message.include?("-txindex")
      TxCatcher::LOGGER.report "WARNING: Pruning is ON, will NOT be able to use RPC requests to check block_height for transactions!", :warn
      return @tx_index_enabled = false
    else
      raise e
    end
  end
end