bitcoin-ruby 0.0.1 → 0.0.2

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 (136) hide show
  1. data/.gitignore +4 -1
  2. data/Gemfile +21 -0
  3. data/README.rdoc +85 -25
  4. data/Rakefile +7 -3
  5. data/bin/bitcoin_node +39 -42
  6. data/bin/bitcoin_shell +1 -0
  7. data/bin/bitcoin_wallet +129 -53
  8. data/bitcoin-ruby.gemspec +4 -7
  9. data/concept-examples/blockchain-pow.rb +1 -1
  10. data/doc/CONFIG.rdoc +5 -5
  11. data/doc/EXAMPLES.rdoc +9 -5
  12. data/doc/NAMECOIN.rdoc +34 -0
  13. data/doc/NODE.rdoc +147 -10
  14. data/examples/balance.rb +10 -4
  15. data/examples/bbe_verify_tx.rb +7 -2
  16. data/examples/forwarder.rb +73 -0
  17. data/examples/generate_tx.rb +34 -0
  18. data/examples/simple_network_monitor_and_util.rb +187 -0
  19. data/examples/verify_tx.rb +1 -1
  20. data/lib/bitcoin.rb +308 -18
  21. data/lib/bitcoin/builder.rb +62 -36
  22. data/lib/bitcoin/config.rb +2 -0
  23. data/lib/bitcoin/connection.rb +11 -8
  24. data/lib/bitcoin/electrum/mnemonic.rb +162 -0
  25. data/lib/bitcoin/ffi/openssl.rb +187 -21
  26. data/lib/bitcoin/gui/addr_view.rb +2 -0
  27. data/lib/bitcoin/gui/conn_view.rb +2 -0
  28. data/lib/bitcoin/gui/connection.rb +2 -0
  29. data/lib/bitcoin/gui/em_gtk.rb +2 -0
  30. data/lib/bitcoin/gui/gui.rb +2 -0
  31. data/lib/bitcoin/gui/helpers.rb +2 -0
  32. data/lib/bitcoin/gui/tree_view.rb +2 -0
  33. data/lib/bitcoin/gui/tx_view.rb +2 -0
  34. data/lib/bitcoin/key.rb +77 -11
  35. data/lib/bitcoin/litecoin.rb +81 -0
  36. data/lib/bitcoin/logger.rb +20 -1
  37. data/lib/bitcoin/namecoin.rb +279 -0
  38. data/lib/bitcoin/network/command_client.rb +7 -6
  39. data/lib/bitcoin/network/command_handler.rb +229 -43
  40. data/lib/bitcoin/network/connection_handler.rb +182 -70
  41. data/lib/bitcoin/network/node.rb +231 -106
  42. data/lib/bitcoin/protocol.rb +44 -23
  43. data/lib/bitcoin/protocol/address.rb +5 -3
  44. data/lib/bitcoin/protocol/alert.rb +3 -4
  45. data/lib/bitcoin/protocol/aux_pow.rb +123 -0
  46. data/lib/bitcoin/protocol/block.rb +98 -18
  47. data/lib/bitcoin/protocol/handler.rb +6 -5
  48. data/lib/bitcoin/protocol/parser.rb +44 -19
  49. data/lib/bitcoin/protocol/tx.rb +105 -52
  50. data/lib/bitcoin/protocol/txin.rb +39 -19
  51. data/lib/bitcoin/protocol/txout.rb +28 -13
  52. data/lib/bitcoin/protocol/version.rb +16 -7
  53. data/lib/bitcoin/script.rb +579 -122
  54. data/lib/bitcoin/storage/{dummy.rb → dummy/dummy_store.rb} +8 -14
  55. data/lib/bitcoin/storage/models.rb +20 -7
  56. data/lib/bitcoin/storage/{sequel_store/sequel_migrations.rb → sequel/migrations.rb} +22 -7
  57. data/lib/bitcoin/storage/sequel/migrations/001_base_schema.rb +52 -0
  58. data/lib/bitcoin/storage/sequel/migrations/002_tx.rb +50 -0
  59. data/lib/bitcoin/storage/sequel/migrations/003_change_txin_script_sig_to_blob.rb +18 -0
  60. data/lib/bitcoin/storage/sequel/sequel_store.rb +436 -0
  61. data/lib/bitcoin/storage/storage.rb +233 -28
  62. data/lib/bitcoin/storage/utxo/migrations/001_base_schema.rb +52 -0
  63. data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +18 -0
  64. data/lib/bitcoin/storage/utxo/utxo_store.rb +361 -0
  65. data/lib/bitcoin/validation.rb +369 -0
  66. data/lib/bitcoin/version.rb +1 -1
  67. data/lib/bitcoin/wallet/coinselector.rb +3 -0
  68. data/lib/bitcoin/wallet/keygenerator.rb +3 -1
  69. data/lib/bitcoin/wallet/keystore.rb +6 -2
  70. data/lib/bitcoin/wallet/txdp.rb +6 -4
  71. data/lib/bitcoin/wallet/wallet.rb +54 -16
  72. data/spec/bitcoin/bitcoin_spec.rb +48 -3
  73. data/spec/bitcoin/builder_spec.rb +40 -17
  74. data/spec/bitcoin/fixtures/000000000000056b1a3d84a1e2b33cde8915a4b61c0cae14fca6d3e1490b4f98.json +3697 -0
  75. data/spec/bitcoin/fixtures/03d7e1fa4d5fefa169431f24f7798552861b255cd55d377066fedcd088fb0e99.json +23 -0
  76. data/spec/bitcoin/fixtures/0961c660358478829505e16a1f028757e54b5bbf9758341a7546573738f31429.json +24 -0
  77. data/spec/bitcoin/fixtures/0f24294a1d23efbb49c1765cf443fba7930702752aba6d765870082fe4f13cae.json +37 -0
  78. data/spec/bitcoin/fixtures/315ac7d4c26d69668129cc352851d9389b4a6868f1509c6c8b66bead11e2619f.json +31 -0
  79. data/spec/bitcoin/fixtures/35e2001b428891fefa0bfb73167c7360669d3cbd7b3aa78e7cad125ddfc51131.json +27 -0
  80. data/spec/bitcoin/fixtures/3a17dace09ffb919ed627a93f1873220f4c975c1248558b18d16bce25d38c4b7.json +72 -0
  81. data/spec/bitcoin/fixtures/3e58b7eed0fdb599019af08578effea25c8666bbe8e200845453cacce6314477.json +27 -0
  82. data/spec/bitcoin/fixtures/514c46f0b61714092f15c8dfcb576c9f79b3f959989b98de3944b19d98832b58.json +24 -0
  83. data/spec/bitcoin/fixtures/51bf528ecf3c161e7c021224197dbe84f9a8564212f6207baa014c01a1668e1e.json +30 -0
  84. data/spec/bitcoin/fixtures/69216b8aaa35b76d6613e5f527f4858640d986e1046238583bdad79b35e938dc.json +28 -0
  85. data/spec/bitcoin/fixtures/7208e5edf525f04e705fb3390194e316205b8f995c8c9fcd8c6093abe04fa27d.json +27 -0
  86. data/spec/bitcoin/fixtures/761d8c5210fdfd505f6dff38f740ae3728eb93d7d0971fb433f685d40a4c04f6.json +27 -0
  87. data/spec/bitcoin/fixtures/aea682d68a3ea5e3583e088dcbd699a5d44d4b083f02ad0aaf2598fe1fa4dfd4.json +27 -0
  88. data/spec/bitcoin/fixtures/bd1715f1abfdc62bea3f605bdb461b3ba1f2cca6ec0d73a18a548b7717ca8531.json +34 -0
  89. data/spec/bitcoin/fixtures/block-testnet-0000000000ac85bb2530a05a4214a387e6be02b22d3348abc5e7a5d9c4ce8dab.bin +0 -0
  90. data/spec/bitcoin/fixtures/cd874fa8cb0e2ec2d385735d5e1fd482c4fe648533efb4c50ee53bda58e15ae2.json +24 -0
  91. data/spec/bitcoin/fixtures/ce5fad9b4ef094d8f4937b0707edaf0a6e6ceeaf67d5edbfd51f660eac8f398b.json +41 -0
  92. data/spec/bitcoin/fixtures/f003f0c1193019db2497a675fd05d9f2edddf9b67c59e677c48d3dbd4ed5f00b.json +23 -0
  93. data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.bin +0 -0
  94. data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.json +43 -0
  95. data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.bin +0 -0
  96. data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.json +67 -0
  97. data/spec/bitcoin/fixtures/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.bin +0 -0
  98. data/spec/bitcoin/fixtures/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.json +39 -0
  99. data/spec/bitcoin/fixtures/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.bin +0 -0
  100. data/spec/bitcoin/fixtures/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.json +39 -0
  101. data/spec/bitcoin/fixtures/rawblock-auxpow.bin +0 -0
  102. data/spec/bitcoin/fixtures/tx-313897799b1e37e9ecae15010e56156dddde4e683c96b0e713af95272c38aee0.json +30 -0
  103. data/spec/bitcoin/fixtures/tx-3da75972766f0ad13319b0b461fd16823a731e44f6e9de4eb3c52d6a6fb6c8ae.json +23 -0
  104. data/spec/bitcoin/fixtures/tx-44b833074e671120ba33106877b49e86ece510824b9af477a3853972bcd8d06a.json +30 -0
  105. data/spec/bitcoin/fixtures/tx-d3d77d63709e47d9ef58f0b557800115a6b676c6a423012fbb96f45d8fcef830.json +28 -0
  106. data/spec/bitcoin/key_spec.rb +128 -3
  107. data/spec/bitcoin/namecoin_spec.rb +182 -0
  108. data/spec/bitcoin/network_spec.rb +5 -3
  109. data/spec/bitcoin/node/command_api_spec.rb +376 -0
  110. data/spec/bitcoin/protocol/addr_spec.rb +2 -0
  111. data/spec/bitcoin/protocol/alert_spec.rb +2 -0
  112. data/spec/bitcoin/protocol/aux_pow_spec.rb +44 -0
  113. data/spec/bitcoin/protocol/block_spec.rb +134 -39
  114. data/spec/bitcoin/protocol/getblocks_spec.rb +32 -0
  115. data/spec/bitcoin/protocol/inv_spec.rb +10 -8
  116. data/spec/bitcoin/protocol/notfound_spec.rb +31 -0
  117. data/spec/bitcoin/protocol/ping_spec.rb +2 -0
  118. data/spec/bitcoin/protocol/tx_spec.rb +83 -17
  119. data/spec/bitcoin/protocol/version_spec.rb +7 -5
  120. data/spec/bitcoin/script/opcodes_spec.rb +412 -133
  121. data/spec/bitcoin/script/script_spec.rb +112 -13
  122. data/spec/bitcoin/spec_helper.rb +68 -0
  123. data/spec/bitcoin/storage/reorg_spec.rb +199 -0
  124. data/spec/bitcoin/storage/storage_spec.rb +337 -0
  125. data/spec/bitcoin/storage/validation_spec.rb +261 -0
  126. data/spec/bitcoin/wallet/coinselector_spec.rb +10 -7
  127. data/spec/bitcoin/wallet/keygenerator_spec.rb +2 -0
  128. data/spec/bitcoin/wallet/keystore_spec.rb +2 -0
  129. data/spec/bitcoin/wallet/txdp_spec.rb +2 -0
  130. data/spec/bitcoin/wallet/wallet_spec.rb +91 -58
  131. metadata +105 -51
  132. data/lib/bitcoin/storage/sequel.rb +0 -335
  133. data/spec/bitcoin/fixtures/0d0affb5964abe804ffe85e53f1dbb9f29e406aa3046e2db04fba240e63c7fdd.json +0 -27
  134. data/spec/bitcoin/fixtures/477fff140b363ec2cc51f3a65c0c58eda38f4d41f04a295bbd62babf25e4c590.json +0 -27
  135. data/spec/bitcoin/reorg_spec.rb +0 -129
  136. data/spec/bitcoin/storage_spec.rb +0 -229
@@ -1,229 +0,0 @@
1
- require_relative 'spec_helper'
2
-
3
- [
4
- # { :name => :dummy },
5
- { :name => :sequel, :db => 'sqlite:/' }, # in memory
6
- # { :name => :sequel, :db => 'sqlite:///tmp/bitcoin_test.db' },
7
- # { :name => :sequel, :db => 'postgres://localhost/bitcoin_test' },
8
- ].each do |configuration|
9
- describe "Bitcoin::Storage::Backends::#{configuration[:name].capitalize}Store" do
10
-
11
- before do
12
- Bitcoin::network = :testnet
13
- Bitcoin::Storage.log.level = 3
14
- @store = Bitcoin::Storage.send(configuration[:name], configuration)
15
- @store.reset
16
-
17
- @store.store_block(Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_0.bin')))
18
- @store.store_block(Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_1.bin')))
19
- @store.store_block(Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_2.bin')))
20
- @store.store_block(Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_3.bin')))
21
-
22
- @store.store_tx(Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-01.bin')))
23
- @store.store_tx(Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-02.bin')))
24
-
25
-
26
- @blk = Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_4.bin'))
27
- @tx = Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-03.bin'))
28
- end
29
-
30
- it "should get depth" do
31
- @store.get_depth.should == 3
32
- end
33
-
34
- it "should report depth as -1 if store is empty" do
35
- @store.reset
36
- @store.get_depth.should == -1
37
- end
38
-
39
- it "should get head" do
40
- @store.get_head
41
- .should == @store.get_block("0000000098932356a236718829dd9e3eb0f9143317ab921333b1a203de336de4")
42
- end
43
-
44
- it "should get locator" do
45
- @store.get_locator.should == [
46
- "0000000098932356a236718829dd9e3eb0f9143317ab921333b1a203de336de4",
47
- "000000037b21cac5d30fc6fda2581cf7b2612908aed2abbcc429c45b0557a15f",
48
- "000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604",
49
- "00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008"]
50
- end
51
-
52
- it "should not store if there is no prev block" do
53
- @store.reset
54
- @store.store_block(@blk).should == [0, 2]
55
- @store.get_depth.should == -1
56
- end
57
-
58
- it "should check whether block is already stored" do
59
- @store.has_block(@blk.hash).should == false
60
- @store.store_block(@blk)
61
- @store.has_block(@blk.hash).should == true
62
- end
63
-
64
- it "should get block by depth" do
65
- @store.get_block_by_depth(0).to_hash.should ==
66
- Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_0.bin')).to_hash
67
- @store.get_block_by_depth(1).to_hash.should ==
68
- Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_1.bin')).to_hash
69
- @store.get_block_by_depth(2).to_hash.should ==
70
- Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_2.bin')).to_hash
71
- end
72
-
73
- it "should get block by hash" do
74
- @store.get_block(
75
- "00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008").to_hash
76
- .should == Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_0.bin')).to_hash
77
- @store.get_block(
78
- "000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604").to_hash
79
- .should == Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_1.bin')).to_hash
80
- @store.get_block(
81
- "000000037b21cac5d30fc6fda2581cf7b2612908aed2abbcc429c45b0557a15f").to_hash
82
- .should == Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_2.bin')).to_hash
83
- end
84
-
85
- it "should not get block" do
86
- @store.get_block("nonexistant").should == nil
87
- end
88
-
89
- it "should get block depth" do
90
- @store.get_block("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")
91
- .depth.should == 0
92
- @store.get_block("000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604")
93
- .depth.should == 1
94
- @store.get_block("000000037b21cac5d30fc6fda2581cf7b2612908aed2abbcc429c45b0557a15f")
95
- .depth.should == 2
96
- end
97
-
98
- it "should get prev block" do
99
- @store.get_block("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")
100
- .get_prev_block.should == nil
101
- @store.get_block("000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604")
102
- .get_prev_block.should ==
103
- @store.get_block("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")
104
- end
105
-
106
- it "should get next block" do
107
- @store.get_block("0000000098932356a236718829dd9e3eb0f9143317ab921333b1a203de336de4")
108
- .get_next_block.should == nil
109
- @store.get_block("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")
110
- .get_next_block.should ==
111
- @store.get_block("000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604")
112
- end
113
-
114
- it "should get block for tx" do
115
- @store.store_block(@blk)
116
- @store.get_block_by_tx(@blk.tx[0].hash).should == @blk
117
- end
118
-
119
- it "should store tx" do
120
- @store.store_tx(@tx).should != false
121
- end
122
-
123
- it "should not store tx if already stored and return existing id" do
124
- id = @store.store_tx(@tx)
125
- @store.store_tx(@tx).should == id
126
- end
127
-
128
- it "should check if tx is already stored" do
129
- @store.has_tx(@tx.hash).should == false
130
- @store.store_tx(@tx)
131
- @store.has_tx(@tx.hash).should == true
132
- end
133
-
134
- it "should store hash160 for txout" do
135
- @store.store_tx(@tx)
136
- @store.get_tx(@tx.hash).out[0].hash160
137
- .should == "3129d7051d509424d23d533fa2d5258977e822e3"
138
- end
139
-
140
- it "should get tx" do
141
- @store.store_tx(@tx)
142
- @store.get_tx(@tx.hash).should == @tx
143
- end
144
-
145
- it "should not get tx" do
146
- @store.get_tx("nonexistant").should == nil
147
- end
148
-
149
-
150
- it "should get txouts for pk script" do
151
- @store.store_block(@blk)
152
- script = @blk.tx[0].out[0].pk_script
153
- @store.get_txouts_for_pk_script(script)
154
- .should == [@blk.tx[0].out[0]]
155
- end
156
-
157
- it "should get block for tx" do
158
- @store.store_block(@blk)
159
- tx = @blk.tx[0]
160
- @store.get_tx(tx.hash).get_block.should == @blk
161
- end
162
-
163
- it "should get tx for txin" do
164
- @store.store_tx(@tx)
165
- @store.get_tx(@tx.hash).in[0].get_tx.should == @tx
166
- end
167
-
168
- it "should get prev out for txin" do
169
- tx = Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.bin'))
170
- outpoint_tx = Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9.bin'))
171
- @store.store_tx(outpoint_tx)
172
- @store.store_tx(tx)
173
-
174
- @store.get_tx(tx.hash).in[0].get_prev_out.should == outpoint_tx.out[0]
175
- end
176
-
177
- it "should get tx for txout" do
178
- @store.store_tx(@tx)
179
- @store.get_tx(@tx.hash).out[0].get_tx.should == @tx
180
- end
181
-
182
- it "should get next in for txin" do
183
- tx = Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.bin'))
184
- outpoint_tx = Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9.bin'))
185
- @store.store_tx(outpoint_tx)
186
- @store.store_tx(tx)
187
-
188
- @store.get_tx(outpoint_tx.hash).out[0].get_next_in.should == tx.in[0]
189
- end
190
-
191
- it "should get txouts for hash160" do
192
- @store.store_tx(@tx)
193
- @store.get_txouts_for_hash160("3129d7051d509424d23d533fa2d5258977e822e3", true)
194
- .should == [@tx.out[0]]
195
- end
196
-
197
- it "should get txouts for address" do
198
- @store.store_tx(@tx)
199
- @store.get_txouts_for_address("mjzuXYR2fncbPzn9nR5Ee5gBgYk9UQx36x", true)
200
- .should == [@tx.out[0]]
201
- end
202
-
203
- it "should get balance for address" do
204
- @store.store_tx(@tx)
205
- @store.get_balance("62e907b15cbf27d5425399ebf6f0fb50ebb88f18").should == 5000000000
206
- @store.get_balance("4580f1b3632948202655fd555fdaaf9b9ef5ac0d").should == 0
207
- end
208
-
209
- it "should store multisig tx and index hash160's" do
210
- (true.should==true) && next if @store.class == Bitcoin::Storage::Backends::DummyStore
211
- *keys = Bitcoin::Key.generate, Bitcoin::Key.generate
212
- pk_script = Bitcoin::Script.to_multisig_script(1, keys[0].pub, keys[1].pub)
213
- txout = Bitcoin::Protocol::TxOut.new(1000, pk_script)
214
- @store.store_txout(0, txout, 0)
215
- keys.each do |key|
216
- hash160 = Bitcoin.hash160(key.pub)
217
- txouts = @store.get_txouts_for_hash160(hash160, true)
218
- txouts.size.should == 1
219
- txouts[0].pk_script.should == txout.pk_script
220
- end
221
- end
222
-
223
- it "should index output script type" do
224
- @store.store_tx(@tx)
225
- @store.get_tx(@tx.hash).out.first.type.should == :hash160
226
- end
227
-
228
- end
229
- end