bitcoin-ruby 0.0.6 → 0.0.7

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 (128) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.travis.yml +2 -7
  4. data/COPYING +1 -1
  5. data/Gemfile +2 -6
  6. data/Gemfile.lock +34 -0
  7. data/README.rdoc +16 -68
  8. data/Rakefile +3 -6
  9. data/bin/bitcoin_shell +0 -1
  10. data/{concept-examples/blockchain-pow.rb → examples/concept-blockchain-pow.rb} +0 -0
  11. data/lib/bitcoin.rb +350 -296
  12. data/lib/bitcoin/builder.rb +3 -1
  13. data/lib/bitcoin/connection.rb +2 -1
  14. data/lib/bitcoin/contracthash.rb +76 -0
  15. data/lib/bitcoin/dogecoin.rb +97 -0
  16. data/lib/bitcoin/ffi/bitcoinconsensus.rb +74 -0
  17. data/lib/bitcoin/ffi/openssl.rb +98 -2
  18. data/lib/bitcoin/ffi/secp256k1.rb +144 -0
  19. data/lib/bitcoin/key.rb +12 -2
  20. data/lib/bitcoin/logger.rb +3 -12
  21. data/lib/bitcoin/protocol/block.rb +3 -9
  22. data/lib/bitcoin/protocol/parser.rb +6 -2
  23. data/lib/bitcoin/protocol/tx.rb +44 -13
  24. data/lib/bitcoin/protocol/txin.rb +4 -2
  25. data/lib/bitcoin/protocol/txout.rb +2 -2
  26. data/lib/bitcoin/script.rb +212 -37
  27. data/lib/bitcoin/trezor/mnemonic.rb +130 -0
  28. data/lib/bitcoin/version.rb +1 -1
  29. data/spec/bitcoin/bitcoin_spec.rb +32 -3
  30. data/spec/bitcoin/builder_spec.rb +18 -0
  31. data/spec/bitcoin/contracthash_spec.rb +45 -0
  32. data/spec/bitcoin/dogecoin_spec.rb +176 -0
  33. data/spec/bitcoin/ffi_openssl.rb +45 -0
  34. data/spec/bitcoin/fixtures/156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a.json +24 -0
  35. data/spec/bitcoin/fixtures/8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c.json +24 -0
  36. data/spec/bitcoin/fixtures/coinbase-toshi.json +33 -0
  37. data/spec/bitcoin/fixtures/coinbase.json +24 -0
  38. data/spec/bitcoin/fixtures/dogecoin-block-60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053.bin +0 -0
  39. data/spec/bitcoin/fixtures/rawtx-01-toshi.json +46 -0
  40. data/spec/bitcoin/fixtures/rawtx-02-toshi.json +46 -0
  41. data/spec/bitcoin/fixtures/rawtx-03-toshi.json +73 -0
  42. data/spec/bitcoin/fixtures/rawtx-testnet-04fdc38d6722ab4b12d79113fc4b2896bdcc5169710690ee4e78541b98e467b4.bin +0 -0
  43. data/spec/bitcoin/fixtures/rawtx-testnet-0b294c7d11dd21bcccb8393e6744fed7d4d1981a08c00e3e88838cc421f33c9f.bin +0 -0
  44. data/spec/bitcoin/fixtures/rawtx-testnet-3bc52ac063291ad92d95ddda5fd776a342083b95607ad32ed8bc6f8f7d30449e.bin +0 -0
  45. data/spec/bitcoin/fixtures/rawtx-testnet-6f0bbdd4e71a8af4305018d738184df32dbb6f27284fdebd5b56d16947f7c181.bin +0 -0
  46. data/spec/bitcoin/fixtures/rawtx-testnet-a7c9b06e275e8674cc19a5f7d3e557c72c6d93576e635b33212dbe08ab7cdb60.bin +0 -0
  47. data/spec/bitcoin/fixtures/rawtx-testnet-f80acbd2f594d04ddb0e1cacba662132104909157dff526935a3c88abe9201a5.bin +0 -0
  48. data/spec/bitcoin/protocol/block_spec.rb +0 -22
  49. data/spec/bitcoin/protocol/tx_spec.rb +145 -2
  50. data/spec/bitcoin/script/script_spec.rb +282 -0
  51. data/spec/bitcoin/secp256k1_spec.rb +48 -0
  52. data/spec/bitcoin/spec_helper.rb +0 -51
  53. data/spec/bitcoin/trezor/mnemonic_spec.rb +161 -0
  54. metadata +48 -98
  55. data/bin/bitcoin_dns_seed +0 -130
  56. data/bin/bitcoin_gui +0 -80
  57. data/bin/bitcoin_node +0 -153
  58. data/bin/bitcoin_node_cli +0 -81
  59. data/bin/bitcoin_wallet +0 -402
  60. data/doc/CONFIG.rdoc +0 -66
  61. data/doc/EXAMPLES.rdoc +0 -13
  62. data/doc/NAMECOIN.rdoc +0 -34
  63. data/doc/NODE.rdoc +0 -225
  64. data/doc/STORAGE.rdoc +0 -33
  65. data/doc/WALLET.rdoc +0 -102
  66. data/examples/balance.rb +0 -66
  67. data/examples/forwarder.rb +0 -73
  68. data/examples/index_nhash.rb +0 -24
  69. data/examples/reindex_p2sh_addrs.rb +0 -44
  70. data/examples/relay_tx.rb +0 -22
  71. data/examples/verify_tx.rb +0 -57
  72. data/lib/bitcoin/config.rb +0 -58
  73. data/lib/bitcoin/gui/addr_view.rb +0 -44
  74. data/lib/bitcoin/gui/bitcoin-ruby.png +0 -0
  75. data/lib/bitcoin/gui/bitcoin-ruby.svg +0 -80
  76. data/lib/bitcoin/gui/conn_view.rb +0 -38
  77. data/lib/bitcoin/gui/connection.rb +0 -70
  78. data/lib/bitcoin/gui/em_gtk.rb +0 -30
  79. data/lib/bitcoin/gui/gui.builder +0 -1643
  80. data/lib/bitcoin/gui/gui.rb +0 -292
  81. data/lib/bitcoin/gui/helpers.rb +0 -115
  82. data/lib/bitcoin/gui/tree_view.rb +0 -84
  83. data/lib/bitcoin/gui/tx_view.rb +0 -69
  84. data/lib/bitcoin/namecoin.rb +0 -280
  85. data/lib/bitcoin/network/command_client.rb +0 -104
  86. data/lib/bitcoin/network/command_handler.rb +0 -570
  87. data/lib/bitcoin/network/connection_handler.rb +0 -387
  88. data/lib/bitcoin/network/node.rb +0 -565
  89. data/lib/bitcoin/storage/dummy/dummy_store.rb +0 -179
  90. data/lib/bitcoin/storage/models.rb +0 -171
  91. data/lib/bitcoin/storage/sequel/migrations.rb +0 -99
  92. data/lib/bitcoin/storage/sequel/migrations/001_base_schema.rb +0 -52
  93. data/lib/bitcoin/storage/sequel/migrations/002_tx.rb +0 -45
  94. data/lib/bitcoin/storage/sequel/migrations/003_change_txin_script_sig_to_blob.rb +0 -18
  95. data/lib/bitcoin/storage/sequel/migrations/004_change_txin_prev_out_to_blob.rb +0 -18
  96. data/lib/bitcoin/storage/sequel/migrations/005_change_tx_hash_to_bytea.rb +0 -14
  97. data/lib/bitcoin/storage/sequel/migrations/006_add_tx_nhash.rb +0 -31
  98. data/lib/bitcoin/storage/sequel/migrations/007_add_prev_out_index_index.rb +0 -16
  99. data/lib/bitcoin/storage/sequel/migrations/008_add_txin_p2sh_type.rb +0 -31
  100. data/lib/bitcoin/storage/sequel/migrations/009_add_addrs_type.rb +0 -56
  101. data/lib/bitcoin/storage/sequel/sequel_store.rb +0 -551
  102. data/lib/bitcoin/storage/storage.rb +0 -517
  103. data/lib/bitcoin/storage/utxo/migrations/001_base_schema.rb +0 -52
  104. data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +0 -18
  105. data/lib/bitcoin/storage/utxo/migrations/003_update_indices.rb +0 -14
  106. data/lib/bitcoin/storage/utxo/migrations/004_add_addrs_type.rb +0 -14
  107. data/lib/bitcoin/storage/utxo/utxo_store.rb +0 -374
  108. data/lib/bitcoin/validation.rb +0 -400
  109. data/lib/bitcoin/wallet/coinselector.rb +0 -33
  110. data/lib/bitcoin/wallet/keygenerator.rb +0 -77
  111. data/lib/bitcoin/wallet/keystore.rb +0 -207
  112. data/lib/bitcoin/wallet/txdp.rb +0 -118
  113. data/lib/bitcoin/wallet/wallet.rb +0 -281
  114. data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.bin +0 -0
  115. data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.json +0 -43
  116. data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.bin +0 -0
  117. data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.json +0 -67
  118. data/spec/bitcoin/namecoin_spec.rb +0 -182
  119. data/spec/bitcoin/node/command_api_spec.rb +0 -663
  120. data/spec/bitcoin/storage/models_spec.rb +0 -104
  121. data/spec/bitcoin/storage/reorg_spec.rb +0 -236
  122. data/spec/bitcoin/storage/storage_spec.rb +0 -387
  123. data/spec/bitcoin/storage/validation_spec.rb +0 -300
  124. data/spec/bitcoin/wallet/coinselector_spec.rb +0 -38
  125. data/spec/bitcoin/wallet/keygenerator_spec.rb +0 -69
  126. data/spec/bitcoin/wallet/keystore_spec.rb +0 -190
  127. data/spec/bitcoin/wallet/txdp_spec.rb +0 -76
  128. data/spec/bitcoin/wallet/wallet_spec.rb +0 -238
@@ -1,43 +0,0 @@
1
- {
2
- "hash":"000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c",
3
- "ver":2,
4
- "prev_block":"000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c",
5
- "mrkl_root":"a0b9ec1d860e0786b0be7380eac76fe6180ca98b20aa03c08097bda1fbbce895",
6
- "time":1356123634,
7
- "bits":486604799,
8
- "nonce":2536343301,
9
- "n_tx":1,
10
- "size":220,
11
- "tx":[
12
- {
13
- "hash":"898cf5a16a1a40342fb193d0ec5dd9de13951c6121b95be96d88042d1e7fcc66",
14
- "ver":2,
15
- "vin_sz":1,
16
- "vout_sz":2,
17
- "lock_time":0,
18
- "size":139,
19
- "in":[
20
- {
21
- "prev_out":{
22
- "hash":"0000000000000000000000000000000000000000000000000000000000000000",
23
- "n":4294967295
24
- },
25
- "coinbase":"51010f062f503253482f"
26
- }
27
- ],
28
- "out":[
29
- {
30
- "value":"254.53572875",
31
- "scriptPubKey":"036c370a402c3e50063d3abd46d49ad174aae679bdc25f2a4ce5a3a4ca15b8b86e OP_CHECKSIG"
32
- },
33
- {
34
- "value":"496.03174604",
35
- "scriptPubKey":"OP_DUP OP_HASH160 85e54144c4020a65fa0a8fdbac8bba75dbc2fd00 OP_EQUALVERIFY OP_CHECKSIG"
36
- }
37
- ]
38
- }
39
- ],
40
- "mrkl_tree":[
41
- "898cf5a16a1a40342fb193d0ec5dd9de13951c6121b95be96d88042d1e7fcc66"
42
- ]
43
- }
@@ -1,67 +0,0 @@
1
- {
2
- "hash":"000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c",
3
- "ver":1,
4
- "prev_block":"0000000000000000000000000000000000000000000000000000000000000000",
5
- "mrkl_root":"f53b1baa971ea40be88cf51288aabd700dfec96c486bf7155a53a4919af4c8bd",
6
- "time":1356123600,
7
- "bits":486604799,
8
- "nonce":278229610,
9
- "n_tx":1,
10
- "size":1374,
11
- "tx":[
12
- {
13
- "hash":"cfc428c86c94c63341d5466b214afd01f3fa4db9471831c233138a257601b102",
14
- "ver":2,
15
- "vin_sz":1,
16
- "vout_sz":8,
17
- "lock_time":0,
18
- "size":1293,
19
- "in":[
20
- {
21
- "prev_out":{
22
- "hash":"0000000000000000000000000000000000000000000000000000000000000000",
23
- "n":4294967295
24
- },
25
- "coinbase":"04ffff001d01044554656c6567726170682032372f4a756e2f3230313220426172636c61797320686974207769746820c2a33239306d2066696e65206f766572204c69626f7220666978696e67"
26
- }
27
- ],
28
- "out":[
29
- {
30
- "value":"254.53671561",
31
- "scriptPubKey":"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f OP_CHECKSIG"
32
- },
33
- {
34
- "value":"0.00000001",
35
- "scriptPubKey":"5029d180e0c5ed798d877b1ada99772986c1422ca932c41b2d04000000000000 OP_DROP 0"
36
- },
37
- {
38
- "value":"0.00000001",
39
- "scriptPubKey":"202020 OP_DROP 4d6574616c73207765726520616e20696d706c696369746c7920616275736976652061677265656d656e742e0a4d6f6465726e2022706170657222206973206120666c6177656420746f6f6c2c2069747320656e67696e656572696e672069732061206e657374206f66206c6565636865732e0a546865206f6c64206d6f6e6579206973206f62736f6c6574652e0a4c65742074686520696e646976696475616c206d6f6e6574697a65206974732063726564697420776974686f75742063617274656c20696e7465726d65646961726965732e0a4769766520757320612072656e742d6c657373206361736820736f2077652063616e206265206672656520666f72207468652066697273742074696d652e0a4c65742074686973206265207468652061776169746564206461776e2e OP_DROP OP_DUP OP_HASH160 0ef0f9d19a653023554146a866238b8822bc84df OP_EQUALVERIFY OP_CHECKSIG"
40
- },
41
- {
42
- "value":"0.00000001",
43
- "scriptPubKey":"2020202020202020 OP_DROP 224c65742075732063616c63756c6174652c20776974686f757420667572746865722061646f2c20696e206f7264657220746f207365652077686f2069732072696768742e22202d2d476f747466726965642057696c68656c6d204c6569626e697a0acebec2b4efbda5e28880efbda560efbc89e38080e38080e38080e3808020206e0aefbfa3e38080e38080e380802020efbcbce38080e380802020efbc882045efbc8920676f6f64206a6f622c206d61616b75210aefbe8ce38080e38080e3808020202fe383bd20e383bd5fefbc8fefbc8f OP_DROP OP_DUP OP_HASH160 c26be5ec809aa4bf6b30aa89823cff7cedc3679a OP_EQUALVERIFY OP_CHECKSIG"
44
- },
45
- {
46
- "value":"0.00000001",
47
- "scriptPubKey":"202020202020 OP_DROP 4963682077c3bc6e736368652046726569636f696e207669656c204572666f6c67207a756d204e75747a656e206465722039392050726f7a656e7421 OP_DROP OP_DUP OP_HASH160 2939acd60037281a708eb11e4e9eda452c029eca OP_EQUALVERIFY OP_CHECKSIG"
48
- },
49
- {
50
- "value":"0.00000001",
51
- "scriptPubKey":"20202020202020202020202020 OP_DROP 225468652076616c7565206f662061206d616e2073686f756c64206265207365656e20696e207768617420686520676976657320616e64206e6f7420696e20776861742068652069732061626c6520746f20726563656976652e22202d2d416c626572742045696e737465696e OP_DROP OP_DUP OP_HASH160 f9ca5caab4bda4dc28b5556aa79a2eec0447f0bf OP_EQUALVERIFY OP_CHECKSIG"
52
- },
53
- {
54
- "value":"0.00000001",
55
- "scriptPubKey":"202020202020202020202020 OP_DROP 22416e2061726d79206f66207072696e6369706c65732063616e2070656e65747261746520776865726520616e2061726d79206f6620736f6c64696572732063616e6e6f742e22202d2d54686f6d6173205061696e65 OP_DROP OP_DUP OP_HASH160 08f320cbb41a1ae25b794f6175f96080681989f3 OP_EQUALVERIFY OP_CHECKSIG"
56
- },
57
- {
58
- "value":"496.03174604",
59
- "scriptPubKey":"OP_DUP OP_HASH160 85e54144c4020a65fa0a8fdbac8bba75dbc2fd00 OP_EQUALVERIFY OP_CHECKSIG"
60
- }
61
- ]
62
- }
63
- ],
64
- "mrkl_tree":[
65
- "cfc428c86c94c63341d5466b214afd01f3fa4db9471831c233138a257601b102"
66
- ]
67
- }
@@ -1,182 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- require_relative 'spec_helper.rb'
4
- require 'bitcoin/script'
5
-
6
- include Bitcoin
7
- include Bitcoin::Builder
8
-
9
- describe 'Bitcoin::Namecoin' do
10
-
11
- describe :script do
12
-
13
- before do
14
- Bitcoin.network = :namecoin
15
- @name_new = Script.from_string("3045022023686b3584247c07f483de4048f3d5136c4faa2f961a6d1e487eb77437422b51022100b1ea62910f2dbb0533d32bd661e8a212d129057d3d71620572278895dbb5c7b501
16
- 04b656d7be83e73344e298feba41b38c52ea50d4583ead0c947fd8019f75c906e0d810c5d167ee616c46d28d7cb5ca1d7a20a180470c9dad79524118bafe6cf569 1 820fa9c6d252d6773e4ef26a2feffa93f0237641 OP_2DROP OP_DUP OP_HASH160 eb86f8f23909e248d199192d8407881c3435a5db OP_EQUALVERIFY OP_CHECKSIG")
17
- @name_firstupdate = Script.from_string("3044022054e1557304c504498f8d40b961373d7401a4e4c1650518db8a9c3a49ee9add7e022061573b2837598c346b21c01969081a309c055d5da23b0ac7e139a6290f2f0a4b01
18
- 04d2628245cdfc6ccf5a762d303ba8a10bd54d597cfdcbf0ac3823bae666a36bb744ed44a2384f42525e37b5b1150c5321718806c0f941904336588dd624f4ce93 2 642f626974636f696e a8c22832fb0d40e900 7b22696e666f223a7b22726567697374726172223a22687474703a2f2f72656769737465722e646f742d6269742e6f7267227d2c22656d61696c223a2022726567697374657240646f742d6269742e6f7267222c226e73223a5b226e73302e7765622d73776565742d7765622e6e6574222c226e73312e7765622d73776565742d7765622e6e6574225d2c226d6170223a7b22223a7b226e73223a5b226e73302e7765622d73776565742d7765622e6e6574222c226e73312e7765622d73776565742d7765622e6e6574225d7d7d7d OP_2DROP OP_2DROP OP_DUP OP_HASH160 f3f4aee9d80da759a4a3547cf6aa95c09881decb OP_EQUALVERIFY OP_CHECKSIG")
19
- @name_update = Script.from_string("304402206a8598a87aadd697732d0a187220023e2b54e542e144d0dee67660c8ca3d66f4022000de36f02afb9162f2d27e947d452d4e28baadfdb21637db2b1f252ad62d7fb201
20
- 04b61d1529dbe912c84d0de898e88ab8a9d9fa4a13e76e7b60419dd3bd2b72021842bbf0f5eba1001d55f0c6f2c255289bedbe843d0164b545bbc056f150b4c3f2 3 642f626974636f696e 7b22696e666f223a7b22726567697374726172223a22687474703a2f2f72656769737465722e646f742d6269742e6f7267227d2c22656d61696c223a2022726567697374657240646f742d6269742e6f7267222c226e73223a5b226e73302e7765622d73776565742d7765622e6e6574222c226e73312e7765622d73776565742d7765622e6e6574225d2c226d6170223a7b22223a7b226e73223a5b226e73302e7765622d73776565742d7765622e6e6574222c226e73312e7765622d73776565742d7765622e6e6574225d7d7d7d OP_2DROP OP_DROP OP_DUP OP_HASH160 8f29c40b89ceda0b9176819e2bb5a15f592c6548 OP_EQUALVERIFY OP_CHECKSIG")
21
- end
22
-
23
- it 'should parse name_new script' do
24
- @name_new.is_name_new?.should == true
25
- @name_firstupdate.is_name_new?.should == false
26
- @name_update.is_name_new?.should == false
27
- end
28
-
29
- it 'should parse name_firstupdate script' do
30
- @name_new.is_name_firstupdate?.should == false
31
- @name_firstupdate.is_name_firstupdate?.should == true
32
- @name_update.is_name_firstupdate?.should == false
33
- end
34
-
35
- it 'should parse name_update script' do
36
- @name_new.is_name_update?.should == false
37
- @name_firstupdate.is_name_update?.should == false
38
- @name_update.is_name_update?.should == true
39
- end
40
-
41
- it 'should run scripts' do
42
- @name_new.run { true }.should == true
43
- @name_firstupdate.run { true }.should == true
44
- @name_update.run { true }.should == true
45
- end
46
-
47
- it 'should get name_hash' do
48
- @name_new.get_namecoin_hash.should == "820fa9c6d252d6773e4ef26a2feffa93f0237641"
49
- end
50
-
51
- it 'should get name' do
52
- @name_firstupdate.get_namecoin_name.should == "d/bitcoin"
53
- @name_update.get_namecoin_name.should == "d/bitcoin"
54
- end
55
-
56
- it 'should get value' do
57
- @name_firstupdate.get_namecoin_value.should == '{"info":{"registrar":"http://register.dot-bit.org"},"email": "register@dot-bit.org","ns":["ns0.web-sweet-web.net","ns1.web-sweet-web.net"],"map":{"":{"ns":["ns0.web-sweet-web.net","ns1.web-sweet-web.net"]}}}'
58
- @name_update.get_namecoin_value.should == @name_firstupdate.get_namecoin_value
59
- end
60
-
61
- def set_rand rand; @rand = rand; end
62
-
63
- it 'should create scripts' do
64
- key = Key.generate
65
- script = Script.to_name_new_script(self, "test/foo", key.addr)
66
- Script.new(script).to_string.should =~
67
- /^1 (.*?) OP_2DROP OP_DUP OP_HASH160 #{key.hash160} OP_EQUALVERIFY OP_CHECKSIG$/
68
- @rand.should != nil
69
-
70
- script = Script.to_name_firstupdate_script("test/foo", "1234", "testing", key.addr)
71
- Script.new(script).to_string.should ==
72
- "2 746573742f666f6f 1234 74657374696e67 OP_2DROP OP_2DROP " +
73
- "OP_DUP OP_HASH160 #{key.hash160} OP_EQUALVERIFY OP_CHECKSIG"
74
-
75
- script = Script.to_name_update_script("test/foo", "more testing", key.addr)
76
- Script.new(script).to_string.should ==
77
- "3 746573742f666f6f 6d6f72652074657374696e67 OP_2DROP OP_DROP " +
78
- "OP_DUP OP_HASH160 #{key.hash160} OP_EQUALVERIFY OP_CHECKSIG"
79
- end
80
-
81
- end
82
-
83
- [
84
- { :name => :utxo, :db => 'sqlite:/', utxo_cache: 0 },
85
- { :name => :sequel, :db => 'sqlite:/' },
86
- ].each do |configuration|
87
-
88
- describe "Namecoin (#{configuration[:name]} store)" do
89
-
90
- before do
91
- Bitcoin.network = :namecoin
92
- Bitcoin.network[:no_difficulty] = true
93
- class Bitcoin::Validation::Block; def min_timestamp; true; end; end
94
- Bitcoin.network[:proof_of_work_limit] = Bitcoin.encode_compact_bits("ff"*32)
95
- [:name_new, :name_firstupdate, :name_update].each {|type|
96
- Bitcoin::Storage::Backends::SequelStore::SCRIPT_TYPES << type }
97
- @store = Bitcoin::Storage.send(configuration[:name], configuration)
98
- @store.reset
99
- @store.log.level = :error
100
- @key = Bitcoin::Key.generate
101
- @block = create_block "00"*32, false, [], @key
102
- Bitcoin.network[:genesis_hash] = @block.hash
103
- @store.store_block(@block)
104
- end
105
-
106
- def set_rand r; @rand = r; end
107
-
108
- it "should store names" do
109
- # create name_new
110
- @block = create_block @block.hash, true, [->(t) {
111
- t.input {|i| i.prev_out @block.tx[0]; i.prev_out_index 0; i.signature_key @key }
112
- t.output {|o| o.value 50e8; o.script {|s| s.type(:name_new)
113
- s.recipient(self, "test", @key.addr) } } }], @key
114
- @store.db[:names][hash: Bitcoin.hash160(@rand + "test".hth)].should != nil
115
-
116
- # name_firstupdate should not be valid yet
117
- @block = create_block @block.hash, true, [->(t) {
118
- t.input {|i| i.prev_out @block.tx[0]; i.prev_out_index 0; i.signature_key @key }
119
- t.output {|o| o.value 50e8; o.script {|s| s.type(:name_firstupdate)
120
- s.recipient("test", @rand, "testvalue", @key.addr) } } }], @key
121
- @store.name_show("test").should == nil
122
-
123
- # create enough blocks for name_new to become valid
124
- Namecoin::FIRSTUPDATE_LIMIT.times {
125
- @block = create_block @block.hash, true, [], @key }
126
-
127
- # name_firstupdate should be valid now
128
- @block = create_block @block.hash, true, [->(t) {
129
- t.input {|i| i.prev_out @block.tx[0]; i.prev_out_index 0; i.signature_key @key }
130
- t.output {|o| o.value 50e8; o.script {|s|; s.type(:name_firstupdate)
131
- s.recipient("test", @rand, "testvalue", @key.addr) } } }], @key
132
-
133
- name = @store.name_show("test")
134
- name.get_address.should == @key.addr
135
- name.name.should == "test"
136
- name.value.should == "testvalue"
137
- name.hash.should == Bitcoin.hash160(@rand + "test".hth)
138
-
139
- # create name_update
140
- @new_key = Bitcoin::Key.generate
141
- @block = create_block @block.hash, true, [->(t) {
142
- t.input {|i| i.prev_out @block.tx[0]; i.prev_out_index 0; i.signature_key @key}
143
- t.output {|o|o.value 50e8; o.script {|s| s.type(:name_update)
144
- s.recipient("test", "testupdate", @new_key.addr) } } }], @new_key
145
-
146
- name = @store.name_show("test")
147
- name.get_address.should == @new_key.addr
148
- name.value.should == "testupdate"
149
-
150
- h = @store.name_history("test")
151
- h.size.should == 2
152
- h[0].value.should == "testvalue"
153
- h[0].get_address.should == @key.addr
154
- h[1].value.should == "testupdate"
155
- h[1].get_address.should == @new_key.addr
156
- end
157
-
158
- it "should expire names" do
159
- @block = create_block @block.hash, true, [->(t) {
160
- t.input {|i| i.prev_out @block.tx[0]; i.prev_out_index 0; i.signature_key @key }
161
- t.output {|o| o.value 50e8; o.script {|s| s.type(:name_new)
162
- s.recipient(self, "test", @key.addr) } } }], @key
163
- @store.db[:names][hash: Bitcoin.hash160(@rand + "test".hth)].should != nil
164
-
165
- # create enough blocks for name_new to become valid
166
- Namecoin::FIRSTUPDATE_LIMIT.times {
167
- @block = create_block @block.hash, true, [], @key }
168
-
169
- # name_firstupdate should be valid now
170
- @block = create_block @block.hash, true, [->(t) {
171
- t.input {|i| i.prev_out @block.tx[0]; i.prev_out_index 0; i.signature_key @key }
172
- t.output {|o| o.value 50e8; o.script {|s|; s.type(:name_firstupdate)
173
- s.recipient("test", @rand, "testvalue", @key.addr) } } }], @key
174
-
175
- @store.name_show("test").expires_in.should == Namecoin::EXPIRATION_DEPTH
176
- @block = create_block @block.hash, true, [], @key
177
- @store.name_show("test").expires_in.should == Namecoin::EXPIRATION_DEPTH - 1
178
- end
179
-
180
- end
181
- end
182
- end
@@ -1,663 +0,0 @@
1
- require_relative '../spec_helper.rb'
2
-
3
- include Bitcoin
4
- include Builder
5
-
6
- class Array
7
- def stringify_keys
8
- map do |e|
9
- (e.is_a?(Array) || e.is_a?(Hash)) ? e.stringify_keys : e
10
- end
11
- end
12
- end
13
-
14
- class Hash
15
- def stringify_keys
16
- Hash[map do |k, v|
17
- v = v.stringify_keys if v.is_a?(Hash) || v.is_a?(Array)
18
- [k.to_s, v]
19
- end]
20
- end
21
- end
22
-
23
- describe 'Node Command API' do
24
-
25
- TSLB_TIMEOUT = 3
26
-
27
- def test_command command, params = nil, response = nil, &block
28
- $responses = {}
29
- EM.run do
30
- @client = Bitcoin::Network::CommandClient.connect(*@config[:command]) do
31
- on_connected do
32
- request(command, params)
33
- end
34
- on_response do |cmd, data|
35
- $responses[cmd] = data
36
- EM.stop
37
- end
38
- end
39
- end
40
-
41
- result = $responses[command]
42
-
43
- return result unless response || block
44
-
45
- if block
46
- block.call(result)
47
- else
48
- raise "ERROR: #{result} != #{response}" unless result.should == response
49
- end
50
- end
51
-
52
-
53
- before do
54
- Bitcoin::Validation::Block::RULES.merge({
55
- syntax: [:hash, :tx_list, :bits, :max_timestamp, :coinbase, :coinbase_scriptsig, :transactions_syntax],
56
- context: [:prev_hash, :coinbase_value, :min_timestamp, :transactions_context]
57
- })
58
-
59
- Bitcoin.network = :spec
60
- @config = {
61
- listen: ["127.0.0.1", 38333],
62
- command: ["127.0.0.1", 38332],
63
- storage: "sequel::sqlite:/",
64
- dns: false,
65
- intervals: { queue: 0.01 },
66
- log: { network: :warn, storage: :warn },
67
- }
68
-
69
- @node = Bitcoin::Network::Node.new(@config)
70
- @pid = fork do
71
- # $stdout = StringIO.new
72
- SimpleCov.running = false if defined?(SimpleCov)
73
- @node.run
74
- end
75
-
76
- @genesis = P::Block.new("0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae180101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000".htb)
77
-
78
- Bitcoin.network[:proof_of_work_limit] = Bitcoin.encode_compact_bits("ff"*32)
79
- @key = Bitcoin::Key.generate
80
- @block = create_block @genesis.hash, false, [], @key
81
-
82
- test_command "store_block", hex: @genesis.to_payload.hth
83
- sleep 0.1
84
-
85
- @id = 0
86
- end
87
-
88
- after do
89
- Process.kill("TERM", @pid)
90
- end
91
-
92
- it "should return error for unknown command" do
93
- test_command("foo", nil, {"error" => "unknown command: foo. send 'help' for help."})
94
- end
95
-
96
- # it "should return error for wrong parameters" do
97
- # test_command("info", "foo", {"error" => "wrong number of arguments (1 for 0)"})
98
- # end
99
-
100
- it "should query tslb" do
101
- test_command("tslb") {|r| (0..TSLB_TIMEOUT).include?(r['tslb']).should == true }
102
- end
103
-
104
- it "should query info" do
105
- info = test_command "info"
106
- info.is_a?(Hash).should == true
107
- info["blocks"].should == { "depth" => 0, "peers" => "?", "sync" => false }
108
- info["addrs"].should == { "alive" => 0, "total" => 0 }
109
- info["connections"].should == {
110
- "established" => 0, "outgoing" => 0, "incoming" => 0, "connecting" => 0 }
111
- info["queue"].should == 0
112
- info["inv_queue"].should == 0
113
- info["inv_cache"].should == 0
114
- info["network"].should == "bitcoin"
115
- info["storage"].should == "sequel::sqlite:/"
116
- info["version"].should == 70001
117
- info["external_ip"].should == "127.0.0.1"
118
- info["uptime"].between?(0, 1).should == true
119
- end
120
-
121
- it "should query config" do
122
- test_command("config").should == JSON.load(@node.config.to_json)
123
- end
124
-
125
- # TODO
126
- it "should query connections" do
127
- test_command("connections").should == []
128
- end
129
-
130
- # TODO
131
- it "should connect" do
132
- test_command("connect", {host: "127.0.0.1", port: 1234})["state"].should == "connecting"
133
- end
134
-
135
- # TODO
136
- it "should disconnect" do
137
- test_command("disconnect", ["127.0.0.1:1234"])["state"].should == "disconnected"
138
- end
139
-
140
- it "should store block" do
141
- test_command("info")["blocks"].should == {"depth" => 0, "peers" => "?", "sync" => false}
142
- res = test_command("store_block", { hex: @block.to_payload.hth })
143
- res.should == { "queued" => @block.hash }
144
- sleep 0.1
145
- test_command("info")["blocks"]["depth"].should == 1
146
- test_command("info")["blocks"]["sync"].should == true
147
- end
148
-
149
- # TODO
150
- # it "should store tx" do
151
- # @tx = @block.tx[1]
152
- # res = test_command("store_tx", { hex: @tx.to_payload.htb })
153
- # res.should == { "queued" => @tx.hash }
154
- # end
155
-
156
- describe :create_tx do
157
-
158
- before do
159
- @key2 = Key.generate
160
- test_command("store_block", hex: @block.to_payload.hth)
161
- sleep 0.1
162
- end
163
-
164
- it "should create transaction from given private keys" do
165
- res = test_command("create_tx", {
166
- keys: [ @key.to_base58 ],
167
- recipients: [[@key2.addr, 10e8], [@key.addr, 40e8]]
168
- })
169
- tx = P::Tx.new(res["hex"].htb)
170
- tx.hash.should == res["hash"]
171
- tx.verify_input_signature(0, @block.tx[0]).should == true
172
- end
173
-
174
- it "should create unsigned transaction from given addresses" do
175
- res = test_command("create_tx", {
176
- keys: [ @key.addr ],
177
- recipients: [[@key2.addr, 10e8], [@key.addr, 40e8]]
178
- })
179
- tx = P::Tx.new(res["hex"].htb)
180
- tx.hash.should == res["hash"]
181
- tx.in[0].script_sig.should == ""
182
- #-> { tx.verify_input_signature(0, @block.tx[0]) }.should.raise(TypeError)
183
- tx.verify_input_signature(0, @block.tx[0]).should == false
184
-
185
- res["missing_sigs"].each.with_index do |sig_data, idx|
186
- sig_hash, sig_addr = *sig_data
187
- sig_addr.should == @key.addr
188
- sig = @key.sign(sig_hash.htb)
189
- script_sig = Script.to_signature_pubkey_script(sig, @key.pub.htb)
190
- tx.in[idx].script_sig_length = script_sig.bytesize
191
- tx.in[idx].script_sig = script_sig
192
- end
193
-
194
- tx.verify_input_signature(0, @block.tx[0]).should == true
195
- end
196
-
197
- it "should create transaction from given pubkeys" do
198
- res = test_command("create_tx", {
199
- keys: [@key.pub],
200
- recipients: [[@key2.addr, 10e8], [@key.addr, 40e8]]
201
- })
202
- tx = P::Tx.new(res["hex"].htb)
203
- tx.hash.should == res["hash"]
204
- #-> { tx.verify_input_signature(0, @block.tx[0]) }.should.raise(TypeError)
205
- tx.verify_input_signature(0, @block.tx[0]).should == false
206
-
207
- res["missing_sigs"].each.with_index do |sig_data, idx|
208
- sig_hash, sig_addr = *sig_data
209
- sig_addr.should == @key.addr
210
- sig = @key.sign(sig_hash.htb)
211
- script_sig = Script.to_signature_pubkey_script(sig, @key.pub.htb)
212
- tx.in[idx].script_sig_length = script_sig.bytesize
213
- tx.in[idx].script_sig = script_sig
214
- end
215
-
216
- tx.verify_input_signature(0, @block.tx[0]).should == true
217
- end
218
-
219
- end
220
-
221
- describe :assemble_tx do
222
-
223
- it "should assemble tx from unsigned tx structure, signatures and pubkeys" do
224
- tx = build_tx do |t|
225
- t.input do |i|
226
- i.prev_out @block.tx[0]
227
- i.prev_out_index 0
228
- end
229
- t.output {|o| o.value 50e8; o.script {|s| s.recipient @key.addr } }
230
- end
231
- sig = @key.sign(tx.in[0].sig_hash)
232
- test_command("store_block", hex: @block.to_payload.hth)
233
- sleep 0.1
234
- res = test_command("assemble_tx", {tx: tx.to_payload.hth, sig_pubs: [[sig.hth, @key.pub]]})
235
- tx = Bitcoin::P::Tx.new(res["hex"].htb)
236
- tx.hash.should == res["hash"]
237
- tx.verify_input_signature(0, @block.tx[0]).should == true
238
- end
239
-
240
- end
241
-
242
- describe :relay_tx do
243
-
244
- it "should handle decoding error" do
245
- res = test_command("relay_tx", hex: "foobar")
246
- res["error"].should == "Error decoding transaction."
247
- end
248
-
249
- it "should handle syntax error" do
250
- # create transaction with invalid output size
251
- block = create_block(@block.hash, false, [->(t) {
252
- create_tx(t, @block.tx[0], 0, [[22e14, @key]]) }], @key)
253
- tx = block.tx[1]
254
-
255
- error = test_command("relay_tx", hex: tx.to_payload.hth)
256
- error["error"].should == "Transaction syntax invalid."
257
- error["details"].should == ["output_values", [22e14, 21e14]]
258
- end
259
-
260
- it "should handle context error" do
261
- # create transaction with invalid input
262
- block = create_block(@block.hash, false, [->(t) {
263
- create_tx(t, @block.tx[0], 0, [[25e8, @key]]) }], @key)
264
- tx = block.tx[1]
265
-
266
- error = test_command("relay_tx", hex: tx.to_payload.hth)
267
- error["error"].should == "Transaction context invalid."
268
- error["details"].should == ["prev_out", [[@block.tx[0].hash, 0]]]
269
- end
270
-
271
- it "should relay transaction" do
272
- block = create_block(@block.hash, false, [->(t) {
273
- create_tx(t, @block.tx[0], 0, [[25e8, @key]]) }], @key)
274
- tx = block.tx[1]
275
-
276
- test_command("store_block", hex: @block.to_payload.hth)
277
- sleep 0.1
278
- res = test_command("relay_tx", hex: tx.to_payload.hth, send: 1, wait: 0)
279
- res["success"].should == true
280
- res["hash"].should == tx.hash
281
- res["propagation"].should == { "sent" => 1, "received" => 0, "percent" => 0.0 }
282
- end
283
-
284
- end
285
-
286
- describe :monitor do
287
-
288
- before do
289
- @client = TCPSocket.new(*@config[:command])
290
-
291
- def send method, params = nil, client = @client
292
- request = { id: @id += 1, method: method, params: params }
293
- client.write(request.to_json + "\x00")
294
- request.stringify_keys
295
- end
296
-
297
- def should_receive request, expected, client = @client
298
- expected = expected.stringify_keys if expected.is_a?(Hash)
299
- begin
300
- Timeout.timeout(100) do
301
- buf = ""
302
- while b = client.read(1)
303
- break if b == "\x00"
304
- buf << b
305
- end
306
- resp = JSON.load(buf)
307
- expected = request.merge(result: expected).stringify_keys
308
- expected.delete("params")
309
- raise "ERROR: #{resp} != #{expected}" unless resp.should == expected
310
- end
311
- rescue Timeout::Error
312
- print " [TIMEOUT]"
313
- :timeout.should == nil
314
- end
315
- end
316
-
317
- def should_receive_block request, block, depth, client = @client
318
- expected = { hash: block.hash, hex: block.to_payload.hth, depth: depth }
319
- should_receive(request, expected, client)
320
- end
321
-
322
- def should_receive_tx request, tx, conf, client = @client
323
- expected = { hash: tx.hash, nhash: tx.nhash, hex: tx.to_payload.hth, conf: conf }
324
- should_receive(request, expected, client)
325
- end
326
-
327
- def should_receive_output request, tx, idx, conf, client = @client
328
- expected = { hash: tx.hash, nhash: tx.nhash, idx: idx,
329
- address: tx.out[idx].parsed_script.get_address, value: tx.out[idx].value, conf: conf }
330
- should_receive(request, expected, client)
331
- end
332
-
333
- def store_block block
334
- request = send("store_block", hex: block.to_payload.hth)
335
- should_receive(request, {"queued" => block.hash })
336
- end
337
-
338
- end
339
-
340
- describe :channels do
341
-
342
- it "should combine multiple channels" do
343
- should_receive r1 = send("monitor", channel: "block"), id: 0
344
- should_receive r2 = send("monitor", channel: "tx", conf: 1), id: 1
345
- store_block @block
346
- should_receive_block(r1, @block, 1)
347
- should_receive_tx(r2, @block.tx[0], 1)
348
- end
349
-
350
- it "should handle multiple clients" do
351
- @client2 = TCPSocket.new(*@config[:command])
352
- should_receive r1_1 = send("monitor", channel: "tx", conf: 1), id: 0
353
- r1_2 = send("monitor", { channel: "block" }, @client2)
354
- should_receive r1_2, { id: 0 }, @client2
355
-
356
- store_block @block
357
-
358
- should_receive_block(r1_2, @block, 1, @client2)
359
- should_receive_tx(r1_1, @block.tx[0], 1)
360
-
361
- block = create_block @block.hash, false
362
- store_block block
363
-
364
- should_receive_block(r1_2, block, 2, @client2)
365
- should_receive_tx(r1_1, block.tx[0], 1)
366
-
367
- r2_2 = send "monitor", { channel: "tx", conf: 1 }, @client2
368
- should_receive r2_2, { id: 1 }, @client2
369
- should_receive r2_1 = send("monitor", channel: "block"), id: 1
370
-
371
- block = create_block block.hash, false
372
- store_block block
373
-
374
- should_receive_block(r1_2, block, 3, @client2)
375
- should_receive_tx(r2_2, block.tx[0], 1, @client2)
376
-
377
- should_receive_tx(r1_1, block.tx[0], 1)
378
-
379
- # if something was wrong, we would now receive the last tx again
380
-
381
- should_receive_block(r2_1, block, 3)
382
-
383
- block = create_block block.hash, false
384
- store_block block
385
-
386
- should_receive_tx(r1_1, block.tx[0], 1)
387
-
388
- should_receive_block(r2_1, block, 4)
389
- should_receive_block(r1_2, block, 4, @client2)
390
- should_receive_tx(r2_2, block.tx[0], 1, @client2)
391
- end
392
-
393
- end
394
-
395
- describe :block do
396
-
397
- before do
398
- @request = send "monitor", channel: "block"
399
-
400
- should_receive(@request, id: 0)
401
- store_block @block
402
- should_receive_block(@request, @block, 1)
403
- end
404
-
405
- it "should monitor block" do
406
- @block = create_block @block.hash, false
407
- store_block @block
408
- should_receive_block(@request, @block, 2)
409
- end
410
-
411
- it "should unmonitor block" do
412
- @request = send "unmonitor", id: 0
413
- should_receive @request, id: 0
414
- store_block create_block(@block.hash, false)
415
-
416
- test_command("tslb") {|r| (0..TSLB_TIMEOUT).include?(r['tslb']).should == true }
417
- end
418
-
419
- it "should not monitor side or orphan blocks" do
420
- @side = create_block @genesis.hash, false
421
- store_block @side
422
-
423
- @orphan = create_block "00" * 32, false
424
- store_block @orphan
425
-
426
- # should not send side or orphan block only the next main block
427
- @block = create_block @block.hash, false
428
- store_block @block
429
-
430
- should_receive_block(@request, @block, 2)
431
- end
432
-
433
- it "should received missed blocks when last block hash is given" do
434
- @client = TCPSocket.new(*@config[:command])
435
- blocks = [@block]
436
- 3.times do
437
- blocks << create_block(blocks.last.hash, false)
438
- store_block blocks.last
439
- end
440
- sleep 0.1
441
-
442
- r = send "monitor", channel: "block", last: blocks[1].hash
443
-
444
- should_receive_block(r, blocks[1], 2)
445
- should_receive_block(r, blocks[2], 3)
446
- should_receive_block(r, blocks[3], 4)
447
- end
448
-
449
- end
450
-
451
- describe :reorg do
452
-
453
- before do
454
- @request = send "monitor", channel: "reorg"
455
- should_receive @request, id: 0
456
- store_block @block
457
- end
458
-
459
- it "should monitor reorg" do
460
- @block1 = create_block @genesis.hash, false
461
- store_block @block1
462
- @block2 = create_block @block1.hash, false
463
- store_block @block2
464
- should_receive @request, { new_main: [ @block1.hash ], new_side: [ @block.hash ] }
465
- end
466
-
467
- it "should unmonitor reorg" do
468
- r = send "unmonitor", id: 0
469
- should_receive r, id: 0
470
- @block1 = create_block @genesis.hash, false
471
- store_block @block1
472
- @block2 = create_block @block1.hash, false
473
- store_block @block2
474
-
475
- test_command("tslb") {|r| (0..TSLB_TIMEOUT).include?(r['tslb']).should == true }
476
- end
477
-
478
- end
479
-
480
- describe :tx do
481
-
482
-
483
- it "should monitor unconfirmed tx" do
484
- r1 = send "monitor", channel: "tx"
485
- should_receive r1, id: 0
486
- tx = @block.tx[0]
487
- r2 = send "store_tx", hex: tx.to_payload.hth
488
- should_receive r2, { "queued" => tx.hash }
489
-
490
- should_receive_tx(r1, tx, 0)
491
- end
492
-
493
- it "should unmonitor tx" do
494
- r1 = send "monitor", channel: "tx"
495
- should_receive r1, id: 0
496
-
497
- r2 = send "unmonitor", id: 0
498
- should_receive r2, id: 0
499
-
500
- tx = @block.tx[0]
501
- r3 = send "store_tx", hex: tx.to_payload.hth
502
- should_receive r3, { "queued" => tx.hash }
503
-
504
- test_command("tslb") {|r| (0..TSLB_TIMEOUT).include?(r['tslb']).should == true }
505
- end
506
-
507
- it "should monitor confirmed tx" do
508
- r = send "monitor", channel: "tx", conf: 1
509
- should_receive r, id: 0
510
- store_block @block
511
-
512
- should_receive_tx(r, @block.tx[0], 1)
513
- end
514
-
515
- it "should monitor tx for given confirmation level" do
516
- r = send "monitor", channel: "tx", conf: 3
517
- should_receive r, id: 0
518
-
519
- @tx = @block.tx[0]
520
- store_block @block
521
- @block = create_block @block.hash, false
522
- store_block @block
523
-
524
- should_receive_tx(r, @genesis.tx[0], 3)
525
-
526
- @block = create_block @block.hash, false
527
- store_block @block
528
-
529
- should_receive_tx(r, @tx, 3)
530
- end
531
-
532
- it "should receive missed txs when last txhash is given" do
533
- @client = TCPSocket.new(*@config[:command])
534
- blocks = [@block]; store_block @block
535
- 3.times do
536
- blocks << create_block(blocks.last.hash, false)
537
- store_block blocks.last
538
- end
539
- sleep 0.1
540
-
541
- r = send "monitor", channel: "tx", conf: 1, last: blocks[0].tx[0].hash
542
-
543
- should_receive_tx(r, blocks[1].tx[0], 3)
544
- should_receive_tx(r, blocks[2].tx[0], 2)
545
- should_receive_tx(r, blocks[3].tx[0], 1)
546
-
547
- should_receive r, id: 0
548
- end
549
-
550
-
551
- it "should filter txs for given addresses" do
552
- @key2 = Bitcoin::Key.generate
553
- block = create_block(@block.hash, false, [->(t) {
554
- create_tx(t, @block.tx[0], 0, [[50e8, @key2]]) }], @key)
555
- @addr = @block.tx[0].out[0].parsed_script.get_address
556
- r = send "monitor", channel: "tx", conf: 1, addresses: [ @key2.addr ]
557
- should_receive r, id: 0
558
- store_block @block
559
- store_block block
560
- should_receive_tx(r, block.tx[1], 1)
561
- end
562
-
563
- end
564
-
565
- describe :output do
566
-
567
- before do
568
- @tx = @block.tx[0]; @out = @tx.out[0]
569
- end
570
-
571
- it "should monitor unconfirmed outputs" do
572
- r1 = send "monitor", channel: "output"
573
- should_receive r1, id: 0
574
- tx = @block.tx[0]
575
- r2 = send "store_tx", hex: tx.to_payload.hth
576
- should_receive r2, { "queued" => tx.hash }
577
- should_receive_output(r1, tx, 0, 0)
578
- end
579
-
580
- it "should unmonitor outputs" do
581
- should_receive send("monitor", channel: "output"), id: 0
582
- should_receive send("unmonitor", id: 0), id: 0
583
-
584
- tx = @block.tx[0]
585
- r2 = send "store_tx", hex: tx.to_payload.hth
586
- should_receive r2, { "queued" => tx.hash }
587
-
588
- test_command("tslb") {|r| (0..TSLB_TIMEOUT).include?(r['tslb']).should == true }
589
- end
590
-
591
- it "should monitor confirmed output" do
592
- r = send "monitor", channel: "output", conf: 1
593
- should_receive r, id: 0
594
- store_block @block
595
- should_receive_output(r, @tx, 0, 1)
596
- end
597
-
598
- it "should monitor output for given confirmation level" do
599
- r = send "monitor", channel: "output", conf: 3
600
- should_receive r, id: 0
601
- store_block @block
602
- @block = create_block @block.hash, false
603
- store_block @block
604
- tx = @genesis.tx[0]; out = tx.out[0]
605
- should_receive_output(r, tx, 0, 3)
606
-
607
- @block = create_block @block.hash, false
608
- store_block @block
609
- should_receive_output(r, @tx, 0, 3)
610
- end
611
-
612
- it "should receive missed outputs when last txhash:idx is given" do
613
- @key = Bitcoin::Key.generate
614
- @client = TCPSocket.new(*@config[:command])
615
- blocks = [@block]; store_block @block
616
- 3.times do
617
- blocks << create_block(blocks.last.hash, false, [], @key)
618
- store_block blocks.last
619
- end
620
- sleep 0.1
621
-
622
- r = send "monitor", channel: "output", conf: 1, last: "#{blocks[0].tx[0].hash}:0"
623
-
624
- should_receive_output(r, blocks[1].tx[0], 0, 3)
625
- should_receive_output(r, blocks[2].tx[0], 0, 2)
626
- should_receive_output(r, blocks[3].tx[0], 0, 1)
627
-
628
- should_receive r, id: 0
629
- end
630
-
631
- it "should filter outputs for given addresses" do
632
- @key2 = Bitcoin::Key.generate
633
- block = create_block(@block.hash, false, [->(t) {
634
- create_tx(t, @block.tx[0], 0, [[50e8, @key2]]) }], @key)
635
-
636
- r = send "monitor", channel: "output", conf: 1, addresses: [ @key2.addr ]
637
- should_receive r, id: 0
638
- store_block @block
639
- store_block block
640
- should_receive_output(r, block.tx[1], 0, 1)
641
- end
642
-
643
- it "should add filter address to output monitor params" do
644
- @key2 = Bitcoin::Key.generate
645
- block = create_block(@block.hash, false, [->(t) {
646
- create_tx(t, @block.tx[0], 0, [[50e8, @key2]]) }], @key)
647
-
648
- r1 = send "monitor", channel: "output", conf: 1, addresses: [ ]
649
- should_receive r1, id: 0
650
-
651
- r2 = send "filter_monitor_output", id: 0, address: @key2.addr
652
- should_receive r2, id: 0
653
-
654
- store_block @block
655
- store_block block
656
- should_receive_output(r1, block.tx[1], 0, 1)
657
- end
658
-
659
- end
660
-
661
- end
662
-
663
- end