bitcoinrb 0.1.3 → 0.1.4

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -0
  3. data/README.md +31 -9
  4. data/bitcoinrb.conf.sample +0 -0
  5. data/bitcoinrb.gemspec +6 -2
  6. data/exe/bitcoinrb-cli +2 -2
  7. data/lib/bitcoin/block_header.rb +9 -2
  8. data/lib/bitcoin/chainparams/regtest.yml +1 -1
  9. data/lib/bitcoin/constants.rb +3 -0
  10. data/lib/bitcoin/key.rb +70 -5
  11. data/lib/bitcoin/logger.rb +25 -1
  12. data/lib/bitcoin/message/addr.rb +0 -39
  13. data/lib/bitcoin/message/headers.rb +1 -0
  14. data/lib/bitcoin/message/inventory.rb +4 -0
  15. data/lib/bitcoin/message/network_addr.rb +44 -0
  16. data/lib/bitcoin/message/version.rb +8 -3
  17. data/lib/bitcoin/message.rb +12 -0
  18. data/lib/bitcoin/mnemonic.rb +2 -2
  19. data/lib/bitcoin/network/connection.rb +14 -1
  20. data/lib/bitcoin/network/message_handler.rb +52 -19
  21. data/lib/bitcoin/network/peer.rb +142 -5
  22. data/lib/bitcoin/network/peer_discovery.rb +16 -8
  23. data/lib/bitcoin/network/pool.rb +39 -14
  24. data/lib/bitcoin/network.rb +0 -1
  25. data/lib/bitcoin/node/cli.rb +66 -0
  26. data/lib/bitcoin/node/configuration.rb +37 -0
  27. data/lib/bitcoin/node/spv.rb +13 -3
  28. data/lib/bitcoin/node.rb +2 -1
  29. data/lib/bitcoin/rpc/http_server.rb +56 -0
  30. data/lib/bitcoin/rpc/request_handler.rb +84 -0
  31. data/lib/bitcoin/rpc.rb +6 -0
  32. data/lib/bitcoin/script/multisig.rb +92 -0
  33. data/lib/bitcoin/script/script.rb +17 -7
  34. data/lib/bitcoin/script/script_interpreter.rb +2 -38
  35. data/lib/bitcoin/store/chain_entry.rb +64 -0
  36. data/lib/bitcoin/store/db/level_db.rb +101 -0
  37. data/lib/bitcoin/store/db.rb +9 -0
  38. data/lib/bitcoin/store/spv_chain.rb +96 -0
  39. data/lib/bitcoin/store.rb +5 -1
  40. data/lib/bitcoin/tx.rb +6 -2
  41. data/lib/bitcoin/version.rb +1 -1
  42. data/lib/bitcoin/wallet/account.rb +82 -0
  43. data/lib/bitcoin/wallet/base.rb +84 -0
  44. data/lib/bitcoin/wallet/db.rb +57 -0
  45. data/lib/bitcoin/wallet/master_key.rb +100 -0
  46. data/lib/bitcoin/wallet.rb +8 -0
  47. data/lib/bitcoin.rb +4 -0
  48. data/lib/openassets/payload.rb +6 -2
  49. metadata +70 -13
  50. data/lib/bitcoin/node/spv_block_chain.rb +0 -15
  51. data/lib/bitcoin/store/spv_block_store.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bad0d642595251361c1e4f281ebe2bb7c08093cd
4
- data.tar.gz: 8a6ce86fdb345abb9fe19b2fb37d80402a92958e
3
+ metadata.gz: 8f25b7f5ff1de3882b880e49e858f3b49bf8c13a
4
+ data.tar.gz: 2a04f3a090503ffdc15d337b351c839d68b33929
5
5
  SHA512:
6
- metadata.gz: f57859bf2c0080092422681fcc9e7f66c6a4605ae4b00dcef291b4f13126264da9bf6c23424aec2450be5f5819364d74e9765159d77b6d9b74de30ddeeb000fd
7
- data.tar.gz: e7682dfea261c6456dc5f9e5c969836d338d5045a445b2141a63d97c9117cfea537b62683fe87dd7baae82e94c98dd5109b617db51933aa3656434c264ec1164
6
+ metadata.gz: abbfff02611cb216dc843414bc7e8e9f4e9799a72314ebc3f165f6b100fa2e2d77843975b77bca8ccce3d23d7fb749eb12c62f881ac7f3635840bb68eedb9791
7
+ data.tar.gz: a0a3fd06f7120bdff5c04375e1ab4214d3e962256d96f4c5f9a48811eeb5227ad602bd7ff2283c117219d3bb4d880dd529a9b0fde1567cc2ef03d2a9b2106cfd
data/.travis.yml CHANGED
@@ -2,3 +2,7 @@ language: ruby
2
2
  rvm:
3
3
  - 2.3.0
4
4
  - 2.4.1
5
+ addons:
6
+ apt:
7
+ packages:
8
+ - libleveldb-dev
data/README.md CHANGED
@@ -1,8 +1,35 @@
1
- # Bitcoinrb
1
+ # Bitcoinrb [![Build Status](https://travis-ci.org/haw-itn/bitcoinrb.svg?branch=master)](https://travis-ci.org/haw-itn/bitcoinrb) [![Gem Version](https://badge.fury.io/rb/bitcoinrb.svg)](https://badge.fury.io/rb/bitcoinrb) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE) <img src="http://segwit.co/static/public/images/logo.png" width="100">
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/bitcoinrb`. To experiment with that code, run `bin/console` for an interactive prompt.
4
3
 
5
- TODO: Delete this and the text above, and describe your gem
4
+ Bitcoinrb is a Ruby implementation of Bitcoin Protocol.
5
+
6
+ NOTE: Bitcoinrb work in progress, and there is a possibility of incompatible change.
7
+
8
+ ## Features
9
+
10
+ Bitcoinrb supports following feature:
11
+
12
+ * Bitcoin script interpreter
13
+ * De/serialization of Bitcoin protocol network messages
14
+ * De/serialization of blocks and transactions
15
+ * Key generation and verification for ECDSA, including [BIP-32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) and [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) supports.
16
+ * Segwit support (parsing segwit payload, Bech32 address, sign for segwit tx, etc..)
17
+ * [WIP] SPV node
18
+ * [WIP] 0ff-chain protocol
19
+
20
+ ## Requirements
21
+
22
+ bitcoinrb requires a `leveldb` library.
23
+
24
+ ### install LevelDB
25
+
26
+ * for Ubuntu
27
+
28
+ $ sudo apt-get install libleveldb-dev
29
+
30
+ + for Mac
31
+
32
+ $ brew install leveldb
6
33
 
7
34
  ## Installation
8
35
 
@@ -20,16 +47,11 @@ Or install it yourself as:
20
47
 
21
48
  $ gem install bitcoinrb
22
49
 
50
+
23
51
  ## Usage
24
52
 
25
53
  TODO: Write usage instructions here
26
54
 
27
- ## Development
28
-
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
-
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
-
33
55
  ## Contributing
34
56
 
35
57
  Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/bitcoinrb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
File without changes
data/bitcoinrb.gemspec CHANGED
@@ -4,6 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'bitcoin/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
+
7
8
  spec.name = "bitcoinrb"
8
9
  spec.version = Bitcoin::VERSION
9
10
  spec.authors = ["azuchi"]
@@ -22,12 +23,15 @@ Gem::Specification.new do |spec|
22
23
  spec.add_runtime_dependency 'ecdsa'
23
24
  spec.add_runtime_dependency 'eventmachine'
24
25
  spec.add_runtime_dependency 'murmurhash3'
25
- spec.add_runtime_dependency 'bech32', '~> 1.0.1'
26
+ spec.add_runtime_dependency 'bech32', '~> 1.0.3'
26
27
  spec.add_runtime_dependency 'daemon-spawn'
27
28
  spec.add_runtime_dependency 'thor'
28
29
  spec.add_runtime_dependency 'ffi'
29
- spec.add_runtime_dependency 'parallel'
30
30
  spec.add_runtime_dependency 'leb128', '~> 1.0.0'
31
+ spec.add_runtime_dependency 'leveldb-ruby'
32
+ spec.add_runtime_dependency 'eventmachine_httpserver'
33
+ spec.add_runtime_dependency 'rest-client'
34
+ spec.add_runtime_dependency 'iniparse'
31
35
 
32
36
  spec.add_development_dependency 'bundler', '~> 1.11'
33
37
  spec.add_development_dependency 'rake', '~> 10.0'
data/exe/bitcoinrb-cli CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'bitcoin/node/spv/cli'
3
+ require 'bitcoin'
4
4
 
5
- Bitcoin::Nodes::SPV::CLI.start(ARGV)
5
+ Bitcoin::Node::CLI.start(ARGV)
@@ -3,7 +3,6 @@ module Bitcoin
3
3
  # Block Header
4
4
  class BlockHeader
5
5
 
6
- attr_accessor :hash
7
6
  attr_accessor :version
8
7
  attr_accessor :prev_hash
9
8
  attr_accessor :merkle_root
@@ -18,7 +17,6 @@ module Bitcoin
18
17
  @time = time
19
18
  @bits = bits
20
19
  @nonce = nonce
21
- @hash = calc_hash
22
20
  end
23
21
 
24
22
  def self.parse_from_payload(payload)
@@ -38,6 +36,11 @@ module Bitcoin
38
36
  (mantissa * 2 ** (8 * (exponent - 3)))
39
37
  end
40
38
 
39
+ # block hash
40
+ def hash
41
+ calc_hash
42
+ end
43
+
41
44
  # evaluate block header
42
45
  def valid?
43
46
  valid_pow? && valid_timestamp?
@@ -62,6 +65,10 @@ module Bitcoin
62
65
  (2**256) / (target + 1)
63
66
  end
64
67
 
68
+ def ==(other)
69
+ other && other.to_payload == to_payload
70
+ end
71
+
65
72
  private
66
73
 
67
74
  def calc_hash
@@ -4,7 +4,7 @@ magic_head: "fabfb5da"
4
4
  message_magic: "Bitcoin Signed Message:\n"
5
5
  address_version: "6f"
6
6
  p2sh_version: "c4"
7
- bech32_hrp: 'tb'
7
+ bech32_hrp: 'bcrt'
8
8
  privkey_version: "ef"
9
9
  extended_privkey_version: "04358394"
10
10
  extended_pubkey_version: "043587cf"
@@ -167,4 +167,7 @@ module Bitcoin
167
167
 
168
168
  # Maximum amount of time that a block timestamp is allowed to exceed the current network-adjusted time before the block will be accepted.
169
169
  MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60
170
+
171
+ # Size of set to pick median time from.
172
+ MEDIAN_TIME_SPAN = 11
170
173
  end
data/lib/bitcoin/key.rb CHANGED
@@ -8,9 +8,16 @@ module Bitcoin
8
8
  attr_accessor :compressed
9
9
  attr_reader :secp256k1_module
10
10
 
11
+ MIN_PRIV_KEy_MOD_ORDER = 0x01
12
+ # Order of secp256k1's generator minus 1.
13
+ MAX_PRIV_KEY_MOD_ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140
14
+
11
15
  def initialize(priv_key: nil, pubkey: nil, compressed: true)
12
16
  @secp256k1_module = Bitcoin.secp_impl
13
17
  @priv_key = priv_key
18
+ if @priv_key
19
+ raise ArgumentError, 'private key is not on curve' unless validate_private_key_range(@priv_key)
20
+ end
14
21
  if pubkey
15
22
  @pubkey = pubkey
16
23
  else
@@ -28,12 +35,23 @@ module Bitcoin
28
35
  # import private key from wif format
29
36
  # https://en.bitcoin.it/wiki/Wallet_import_format
30
37
  def self.from_wif(wif)
31
- compressed = wif.size == 52
32
38
  hex = Base58.decode(wif)
33
- version, key, flag, checksum = hex.unpack("a2a64a#{compressed ? 2 : 0}a8")
39
+ raise ArgumentError, 'data is too short' if hex.htb.bytesize < 4
40
+ version = hex[0..1]
41
+ data = hex[2...-8].htb
42
+ checksum = hex[-8..-1]
34
43
  raise ArgumentError, 'invalid version' unless version == Bitcoin.chain_params.privkey_version
35
- raise ArgumentError, 'invalid checksum' unless Bitcoin.calc_checksum(version + key + flag) == checksum
36
- new(priv_key: key, compressed: compressed)
44
+ raise ArgumentError, 'invalid checksum' unless Bitcoin.calc_checksum(version + data.bth) == checksum
45
+ key_len = data.bytesize
46
+ if key_len == 33 && data[-1].unpack('C').first == 1
47
+ compressed = true
48
+ data = data[0..-2]
49
+ elsif key_len == 32
50
+ compressed = false
51
+ else
52
+ raise ArgumentError, 'Wrong number of bytes for a private key, not 32 or 33'
53
+ end
54
+ new(priv_key: data.bth, compressed: compressed)
37
55
  end
38
56
 
39
57
  # export private key with wif format
@@ -47,7 +65,12 @@ module Bitcoin
47
65
 
48
66
  # sign +data+ with private key
49
67
  def sign(data)
50
- secp256k1_module.sign_data(data, priv_key)
68
+ sig = nil
69
+ until sig
70
+ signature = secp256k1_module.sign_data(data, priv_key)
71
+ sig = signature if Key.low_signature?(signature)
72
+ end
73
+ sig
51
74
  end
52
75
 
53
76
  # verify signature using public key
@@ -116,6 +139,42 @@ module Bitcoin
116
139
  compare_big_endian(val_s, max_mod_half_order) <= 0
117
140
  end
118
141
 
142
+
143
+ # check +sig+ is correct der encoding.
144
+ # This function is consensus-critical since BIP66.
145
+ def self.valid_signature_encoding?(sig)
146
+ return false if sig.bytesize < 9 || sig.bytesize > 73 # Minimum and maximum size check
147
+
148
+ s = sig.unpack('C*')
149
+
150
+ return false if s[0] != 0x30 || s[1] != s.size - 3 # A signature is of type 0x30 (compound). Make sure the length covers the entire signature.
151
+
152
+ len_r = s[3]
153
+ return false if 5 + len_r >= s.size # Make sure the length of the S element is still inside the signature.
154
+
155
+ len_s = s[5 + len_r]
156
+ return false unless len_r + len_s + 7 == s.size #Verify that the length of the signature matches the sum of the length of the elements.
157
+
158
+ return false unless s[2] == 0x02 # Check whether the R element is an integer.
159
+
160
+ return false if len_r == 0 # Zero-length integers are not allowed for R.
161
+
162
+ return false unless s[4] & 0x80 == 0 # Negative numbers are not allowed for R.
163
+
164
+ # Null bytes at the start of R are not allowed, unless R would otherwise be interpreted as a negative number.
165
+ return false if len_r > 1 && (s[4] == 0x00) && (s[5] & 0x80 == 0)
166
+
167
+ return false unless s[len_r + 4] == 0x02 # Check whether the S element is an integer.
168
+
169
+ return false if len_s == 0 # Zero-length integers are not allowed for S.
170
+ return false unless (s[len_r + 6] & 0x80) == 0 # Negative numbers are not allowed for S.
171
+
172
+ # Null bytes at the start of S are not allowed, unless S would otherwise be interpreted as a negative number.
173
+ return false if len_s > 1 && (s[len_r + 6] == 0x00) && (s[len_r + 7] & 0x80 == 0)
174
+
175
+ true
176
+ end
177
+
119
178
  private
120
179
 
121
180
  def self.compare_big_endian(c1, c2)
@@ -144,6 +203,12 @@ module Bitcoin
144
203
  pubkey.bth
145
204
  end
146
205
 
206
+ # check private key range.
207
+ def validate_private_key_range(private_key)
208
+ value = private_key.to_i(16)
209
+ MIN_PRIV_KEy_MOD_ORDER <= value && value <= MAX_PRIV_KEY_MOD_ORDER
210
+ end
211
+
147
212
  end
148
213
 
149
214
  end
@@ -5,14 +5,38 @@ module Bitcoin
5
5
  # Simple Logger module
6
6
  module Logger
7
7
 
8
+ Format = "%s, [%s#%d #%d] %5s -- %s: %s\n".freeze
9
+
10
+ module_function
11
+
8
12
  # Create a logger with given +name+.log in $HOME/.bitcoinrb/log.
9
- def self.create(name, level = ::Logger::INFO)
13
+ def create(name, level = ::Logger::INFO)
10
14
  dir = "#{Bitcoin.base_dir}/log"
11
15
  FileUtils.mkdir_p(dir)
12
16
  logger = ::Logger.new(dir + "/#{name}.log", 10)
13
17
  logger.level = level
18
+ logger.formatter = proc do |severity, datetime, progname, msg|
19
+ Format % [severity[0..0], format_datetime(datetime), $$,
20
+ Thread.current.object_id, severity, progname, msg2str(msg)]
21
+ end
14
22
  logger
15
23
  end
16
24
 
25
+ def self.msg2str(msg)
26
+ case msg
27
+ when ::String
28
+ msg
29
+ when ::Exception
30
+ "#{ msg.message } (#{ msg.class })\n" <<
31
+ (msg.backtrace || []).join("\n")
32
+ else
33
+ msg.inspect
34
+ end
35
+ end
36
+
37
+ def format_datetime(time)
38
+ time.strftime(@datetime_format || "%Y-%m-%dT%H:%M:%S.%6N ".freeze)
39
+ end
40
+
17
41
  end
18
42
  end
@@ -31,44 +31,5 @@ module Bitcoin
31
31
 
32
32
  end
33
33
 
34
- class NetworkAddr
35
-
36
- # unix time.
37
- # Nodes advertising their own IP address set this to the current time.
38
- # Nodes advertising IP addresses they’ve connected to set this to the last time they connected to that node.
39
- # Other nodes just relaying the IP address should not change the time. Nodes can use the time field to avoid relaying old addr messages.
40
- attr_accessor :time
41
-
42
- # The services the node advertised in its version message.
43
- attr_accessor :services
44
-
45
- attr_accessor :ip
46
-
47
- attr_accessor :port
48
-
49
- def initialize
50
- @time = Time.now.to_i
51
- @services = Bitcoin::Message::SERVICE_FLAGS[:network]
52
- end
53
-
54
- def self.parse_from_payload(payload)
55
- buf = payload.is_a?(String) ? StringIO.new(payload) : payload
56
- addr = new
57
- addr.time = buf.read(4).unpack('V').first
58
- addr.services = buf.read(8).unpack('Q').first
59
- ip = IPAddr::new_ntoh(buf.read(16))
60
- addr.ip = ip.ipv4_mapped? ? ip.native : ip.to_s
61
- addr.port = buf.read(2).unpack('n').first
62
- addr
63
- end
64
-
65
- def to_payload
66
- ip_addr = IPAddr.new (ip)
67
- ip_addr = ip_addr.ipv4_mapped if ip_addr.ipv4?
68
- [time, services].pack('VQ') << ip_addr.hton << [port].pack('n')
69
- end
70
-
71
- end
72
-
73
34
  end
74
35
  end
@@ -7,6 +7,7 @@ module Bitcoin
7
7
 
8
8
  COMMAND = 'headers'
9
9
 
10
+ # Array[Bitcoin::BlockHeader]
10
11
  attr_accessor :headers
11
12
 
12
13
  def initialize(headers = [])
@@ -35,6 +35,10 @@ module Bitcoin
35
35
  [identifier].pack('V') << hash.htb.reverse
36
36
  end
37
37
 
38
+ def block?
39
+ [MSG_BLOCK, MSG_WITNESS_BLOCK, MSG_FILTERED_WITNESS_BLOCK].include?(identifier)
40
+ end
41
+
38
42
  private
39
43
 
40
44
  def valid_identifier?(identifier)
@@ -0,0 +1,44 @@
1
+ module Bitcoin
2
+ module Message
3
+
4
+ class NetworkAddr
5
+
6
+ # unix time.
7
+ # Nodes advertising their own IP address set this to the current time.
8
+ # Nodes advertising IP addresses they’ve connected to set this to the last time they connected to that node.
9
+ # Other nodes just relaying the IP address should not change the time. Nodes can use the time field to avoid relaying old addr messages.
10
+ attr_accessor :time
11
+
12
+ # The services the node advertised in its version message.
13
+ attr_accessor :services
14
+
15
+ attr_accessor :ip
16
+
17
+ attr_accessor :port
18
+
19
+ def initialize
20
+ @time = Time.now.to_i
21
+ @services = Bitcoin::Message::SERVICE_FLAGS[:network]
22
+ end
23
+
24
+ def self.parse_from_payload(payload)
25
+ buf = payload.is_a?(String) ? StringIO.new(payload) : payload
26
+ addr = new
27
+ addr.time = buf.read(4).unpack('V').first
28
+ addr.services = buf.read(8).unpack('Q').first
29
+ ip = IPAddr::new_ntoh(buf.read(16))
30
+ addr.ip = ip.ipv4_mapped? ? ip.native : ip.to_s
31
+ addr.port = buf.read(2).unpack('n').first
32
+ addr
33
+ end
34
+
35
+ def to_payload
36
+ ip_addr = IPAddr.new (ip)
37
+ ip_addr = ip_addr.ipv4_mapped if ip_addr.ipv4?
38
+ [time, services].pack('VQ') << ip_addr.hton << [port].pack('n')
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+ end
@@ -1,4 +1,5 @@
1
1
  # encoding: ascii-8bit
2
+ require 'ipaddr'
2
3
  module Bitcoin
3
4
  module Message
4
5
 
@@ -60,9 +61,13 @@ module Bitcoin
60
61
  end
61
62
 
62
63
  def pack_addr(addr)
63
- host, port = addr.split(':')
64
- sockaddr = Socket.pack_sockaddr_in(port.to_i, host)
65
- [[1].pack('Q'), "\x00" * 10, "\xFF\xFF", sockaddr[4...8], sockaddr[2...4]].join
64
+ separator = addr.rindex(':')
65
+ ip = addr[0...separator]
66
+ port = addr[separator + 1..-1].to_i
67
+ ip_addr = IPAddr.new(ip)
68
+ ip_addr = ip_addr.ipv4_mapped if ip_addr.ipv4?
69
+ [1].pack('Q') << ip_addr.hton << [port].pack('n')
70
+ # [[1].pack('Q'), "\x00" * 10, "\xFF\xFF", sockaddr[4...8], sockaddr[2...4]].join
66
71
  end
67
72
 
68
73
  def unpack_addr(addr)
@@ -8,6 +8,7 @@ module Bitcoin
8
8
  autoload :Version, 'bitcoin/message/version'
9
9
  autoload :VerAck, 'bitcoin/message/ver_ack'
10
10
  autoload :Addr, 'bitcoin/message/addr'
11
+ autoload :NetworkAddr, 'bitcoin/message/network_addr'
11
12
  autoload :Block, 'bitcoin/message/block'
12
13
  autoload :FilterLoad, 'bitcoin/message/filter_load'
13
14
  autoload :FilterAdd, 'bitcoin/message/filter_add'
@@ -47,5 +48,16 @@ module Bitcoin
47
48
 
48
49
  DEFAULT_STOP_HASH = "00"*32
49
50
 
51
+ # the protocol version.
52
+ VERSION = {
53
+ headers: 31800,
54
+ pong: 60001,
55
+ bloom: 70011,
56
+ send_headers: 70012,
57
+ fee_filter: 70013,
58
+ compact: 70014,
59
+ compact_witness: 70015
60
+ }
61
+
50
62
  end
51
63
  end
@@ -24,7 +24,7 @@ module Bitcoin
24
24
  def to_entropy(words)
25
25
  word_master = load_words
26
26
  mnemonic = words.map do |w|
27
- index = word_master.index(w)
27
+ index = word_master.index(w.downcase)
28
28
  raise IndexError, 'word not found in words list.' unless index
29
29
  index.to_s(2).rjust(11, '0')
30
30
  end.join
@@ -52,7 +52,7 @@ module Bitcoin
52
52
  # @param [String] passphrase a passphrase which protects mnemonic. the default value is an empty string.
53
53
  # @return [String] seed
54
54
  def to_seed(mnemonic, passphrase: '')
55
- OpenSSL::PKCS5.pbkdf2_hmac(mnemonic.join(' '),
55
+ OpenSSL::PKCS5.pbkdf2_hmac(mnemonic.join(' ').downcase,
56
56
  'mnemonic' + passphrase, 2048, 64, OpenSSL::Digest::SHA512.new).bth
57
57
  end
58
58
 
@@ -20,7 +20,7 @@ module Bitcoin
20
20
 
21
21
  def initialize(peer)
22
22
  @peer = peer
23
- @logger = Bitcoin::Logger.create(:debug)
23
+ @logger = peer.logger
24
24
  @sendheaders = false
25
25
  @attr_accessor = 0
26
26
  @message = ''
@@ -28,6 +28,7 @@ module Bitcoin
28
28
 
29
29
  def post_init
30
30
  logger.info "connected. #{addr}"
31
+ peer.conn_time = Time.now.to_i
31
32
  begin_handshake
32
33
  end
33
34
 
@@ -51,6 +52,18 @@ module Bitcoin
51
52
  EM.stop
52
53
  end
53
54
 
55
+ def handle_error(e)
56
+ peer.handle_error(e)
57
+ end
58
+
59
+ private
60
+
61
+ # start handshake
62
+ def begin_handshake
63
+ logger.info "begin handshake with #{addr}"
64
+ send_message(peer.local_version)
65
+ end
66
+
54
67
  end
55
68
 
56
69
  end