bitcoin-ruby 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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