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.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.travis.yml +2 -7
- data/COPYING +1 -1
- data/Gemfile +2 -6
- data/Gemfile.lock +34 -0
- data/README.rdoc +16 -68
- data/Rakefile +3 -6
- data/bin/bitcoin_shell +0 -1
- data/{concept-examples/blockchain-pow.rb → examples/concept-blockchain-pow.rb} +0 -0
- data/lib/bitcoin.rb +350 -296
- data/lib/bitcoin/builder.rb +3 -1
- data/lib/bitcoin/connection.rb +2 -1
- data/lib/bitcoin/contracthash.rb +76 -0
- data/lib/bitcoin/dogecoin.rb +97 -0
- data/lib/bitcoin/ffi/bitcoinconsensus.rb +74 -0
- data/lib/bitcoin/ffi/openssl.rb +98 -2
- data/lib/bitcoin/ffi/secp256k1.rb +144 -0
- data/lib/bitcoin/key.rb +12 -2
- data/lib/bitcoin/logger.rb +3 -12
- data/lib/bitcoin/protocol/block.rb +3 -9
- data/lib/bitcoin/protocol/parser.rb +6 -2
- data/lib/bitcoin/protocol/tx.rb +44 -13
- data/lib/bitcoin/protocol/txin.rb +4 -2
- data/lib/bitcoin/protocol/txout.rb +2 -2
- data/lib/bitcoin/script.rb +212 -37
- data/lib/bitcoin/trezor/mnemonic.rb +130 -0
- data/lib/bitcoin/version.rb +1 -1
- data/spec/bitcoin/bitcoin_spec.rb +32 -3
- data/spec/bitcoin/builder_spec.rb +18 -0
- data/spec/bitcoin/contracthash_spec.rb +45 -0
- data/spec/bitcoin/dogecoin_spec.rb +176 -0
- data/spec/bitcoin/ffi_openssl.rb +45 -0
- data/spec/bitcoin/fixtures/156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a.json +24 -0
- data/spec/bitcoin/fixtures/8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c.json +24 -0
- data/spec/bitcoin/fixtures/coinbase-toshi.json +33 -0
- data/spec/bitcoin/fixtures/coinbase.json +24 -0
- data/spec/bitcoin/fixtures/dogecoin-block-60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-01-toshi.json +46 -0
- data/spec/bitcoin/fixtures/rawtx-02-toshi.json +46 -0
- data/spec/bitcoin/fixtures/rawtx-03-toshi.json +73 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-04fdc38d6722ab4b12d79113fc4b2896bdcc5169710690ee4e78541b98e467b4.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-0b294c7d11dd21bcccb8393e6744fed7d4d1981a08c00e3e88838cc421f33c9f.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-3bc52ac063291ad92d95ddda5fd776a342083b95607ad32ed8bc6f8f7d30449e.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-6f0bbdd4e71a8af4305018d738184df32dbb6f27284fdebd5b56d16947f7c181.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-a7c9b06e275e8674cc19a5f7d3e557c72c6d93576e635b33212dbe08ab7cdb60.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-f80acbd2f594d04ddb0e1cacba662132104909157dff526935a3c88abe9201a5.bin +0 -0
- data/spec/bitcoin/protocol/block_spec.rb +0 -22
- data/spec/bitcoin/protocol/tx_spec.rb +145 -2
- data/spec/bitcoin/script/script_spec.rb +282 -0
- data/spec/bitcoin/secp256k1_spec.rb +48 -0
- data/spec/bitcoin/spec_helper.rb +0 -51
- data/spec/bitcoin/trezor/mnemonic_spec.rb +161 -0
- metadata +48 -98
- data/bin/bitcoin_dns_seed +0 -130
- data/bin/bitcoin_gui +0 -80
- data/bin/bitcoin_node +0 -153
- data/bin/bitcoin_node_cli +0 -81
- data/bin/bitcoin_wallet +0 -402
- data/doc/CONFIG.rdoc +0 -66
- data/doc/EXAMPLES.rdoc +0 -13
- data/doc/NAMECOIN.rdoc +0 -34
- data/doc/NODE.rdoc +0 -225
- data/doc/STORAGE.rdoc +0 -33
- data/doc/WALLET.rdoc +0 -102
- data/examples/balance.rb +0 -66
- data/examples/forwarder.rb +0 -73
- data/examples/index_nhash.rb +0 -24
- data/examples/reindex_p2sh_addrs.rb +0 -44
- data/examples/relay_tx.rb +0 -22
- data/examples/verify_tx.rb +0 -57
- data/lib/bitcoin/config.rb +0 -58
- data/lib/bitcoin/gui/addr_view.rb +0 -44
- data/lib/bitcoin/gui/bitcoin-ruby.png +0 -0
- data/lib/bitcoin/gui/bitcoin-ruby.svg +0 -80
- data/lib/bitcoin/gui/conn_view.rb +0 -38
- data/lib/bitcoin/gui/connection.rb +0 -70
- data/lib/bitcoin/gui/em_gtk.rb +0 -30
- data/lib/bitcoin/gui/gui.builder +0 -1643
- data/lib/bitcoin/gui/gui.rb +0 -292
- data/lib/bitcoin/gui/helpers.rb +0 -115
- data/lib/bitcoin/gui/tree_view.rb +0 -84
- data/lib/bitcoin/gui/tx_view.rb +0 -69
- data/lib/bitcoin/namecoin.rb +0 -280
- data/lib/bitcoin/network/command_client.rb +0 -104
- data/lib/bitcoin/network/command_handler.rb +0 -570
- data/lib/bitcoin/network/connection_handler.rb +0 -387
- data/lib/bitcoin/network/node.rb +0 -565
- data/lib/bitcoin/storage/dummy/dummy_store.rb +0 -179
- data/lib/bitcoin/storage/models.rb +0 -171
- data/lib/bitcoin/storage/sequel/migrations.rb +0 -99
- data/lib/bitcoin/storage/sequel/migrations/001_base_schema.rb +0 -52
- data/lib/bitcoin/storage/sequel/migrations/002_tx.rb +0 -45
- data/lib/bitcoin/storage/sequel/migrations/003_change_txin_script_sig_to_blob.rb +0 -18
- data/lib/bitcoin/storage/sequel/migrations/004_change_txin_prev_out_to_blob.rb +0 -18
- data/lib/bitcoin/storage/sequel/migrations/005_change_tx_hash_to_bytea.rb +0 -14
- data/lib/bitcoin/storage/sequel/migrations/006_add_tx_nhash.rb +0 -31
- data/lib/bitcoin/storage/sequel/migrations/007_add_prev_out_index_index.rb +0 -16
- data/lib/bitcoin/storage/sequel/migrations/008_add_txin_p2sh_type.rb +0 -31
- data/lib/bitcoin/storage/sequel/migrations/009_add_addrs_type.rb +0 -56
- data/lib/bitcoin/storage/sequel/sequel_store.rb +0 -551
- data/lib/bitcoin/storage/storage.rb +0 -517
- data/lib/bitcoin/storage/utxo/migrations/001_base_schema.rb +0 -52
- data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +0 -18
- data/lib/bitcoin/storage/utxo/migrations/003_update_indices.rb +0 -14
- data/lib/bitcoin/storage/utxo/migrations/004_add_addrs_type.rb +0 -14
- data/lib/bitcoin/storage/utxo/utxo_store.rb +0 -374
- data/lib/bitcoin/validation.rb +0 -400
- data/lib/bitcoin/wallet/coinselector.rb +0 -33
- data/lib/bitcoin/wallet/keygenerator.rb +0 -77
- data/lib/bitcoin/wallet/keystore.rb +0 -207
- data/lib/bitcoin/wallet/txdp.rb +0 -118
- data/lib/bitcoin/wallet/wallet.rb +0 -281
- data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.bin +0 -0
- data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.json +0 -43
- data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.bin +0 -0
- data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.json +0 -67
- data/spec/bitcoin/namecoin_spec.rb +0 -182
- data/spec/bitcoin/node/command_api_spec.rb +0 -663
- data/spec/bitcoin/storage/models_spec.rb +0 -104
- data/spec/bitcoin/storage/reorg_spec.rb +0 -236
- data/spec/bitcoin/storage/storage_spec.rb +0 -387
- data/spec/bitcoin/storage/validation_spec.rb +0 -300
- data/spec/bitcoin/wallet/coinselector_spec.rb +0 -38
- data/spec/bitcoin/wallet/keygenerator_spec.rb +0 -69
- data/spec/bitcoin/wallet/keystore_spec.rb +0 -190
- data/spec/bitcoin/wallet/txdp_spec.rb +0 -76
- data/spec/bitcoin/wallet/wallet_spec.rb +0 -238
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
# encoding: ascii-8bit
|
|
2
|
-
|
|
3
|
-
require_relative '../spec_helper'
|
|
4
|
-
|
|
5
|
-
include Bitcoin
|
|
6
|
-
include Bitcoin::Storage
|
|
7
|
-
include Bitcoin::Storage::Backends
|
|
8
|
-
include Bitcoin::Builder
|
|
9
|
-
|
|
10
|
-
Bitcoin::network = :testnet
|
|
11
|
-
[
|
|
12
|
-
# [:dummy],
|
|
13
|
-
[:sequel, :sqlite],
|
|
14
|
-
# [:utxo, :sqlite, index_all_addrs: true],
|
|
15
|
-
[:sequel, :postgres],
|
|
16
|
-
[:utxo, :postgres, index_all_addrs: true],
|
|
17
|
-
[:sequel, :mysql],
|
|
18
|
-
[:utxo, :mysql, index_all_addrs: true],
|
|
19
|
-
].compact.each do |options|
|
|
20
|
-
next unless storage = setup_db(*options)
|
|
21
|
-
|
|
22
|
-
describe "Storage::Models (#{options[0].to_s.capitalize}Store, #{options[1]})" do
|
|
23
|
-
|
|
24
|
-
before do
|
|
25
|
-
Bitcoin.network[:no_difficulty] = true
|
|
26
|
-
Bitcoin.network[:proof_of_work_limit] = Bitcoin.encode_compact_bits("ff"*32)
|
|
27
|
-
|
|
28
|
-
@store = storage
|
|
29
|
-
def @store.in_sync?; true; end
|
|
30
|
-
@store.reset
|
|
31
|
-
|
|
32
|
-
@store.store_block(P::Block.new(fixtures_file('testnet/block_0.bin')))
|
|
33
|
-
@store.store_block(P::Block.new(fixtures_file('testnet/block_1.bin')))
|
|
34
|
-
@store.store_block(P::Block.new(fixtures_file('testnet/block_2.bin')))
|
|
35
|
-
@store.store_block(P::Block.new(fixtures_file('testnet/block_3.bin')))
|
|
36
|
-
|
|
37
|
-
unless @store.class.name =~ /UtxoStore/
|
|
38
|
-
@store.store_tx(P::Tx.new(fixtures_file('rawtx-01.bin')), false)
|
|
39
|
-
@store.store_tx(P::Tx.new(fixtures_file('rawtx-02.bin')), false)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
@blk = P::Block.new(fixtures_file('testnet/block_4.bin'))
|
|
43
|
-
@tx = P::Tx.new(fixtures_file('rawtx-03.bin'))
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
after do
|
|
47
|
-
Bitcoin.network.delete :no_difficulty
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
describe "Block" do
|
|
51
|
-
|
|
52
|
-
before { @block = @store.get_block_by_depth(1) }
|
|
53
|
-
|
|
54
|
-
it "should get prev block" do
|
|
55
|
-
@block.get_prev_block.should == @store.get_block_by_depth(0)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
it "should get next block" do
|
|
59
|
-
@block.get_next_block.should == @store.get_block_by_depth(2)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it "should get total out" do
|
|
63
|
-
@block.total_out.should == 5000000000
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it "should get total in" do
|
|
67
|
-
@block.total_in.should == 5000000000
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
it "should get total fee" do
|
|
71
|
-
@block.total_fee.should == 0
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
describe "Tx" do
|
|
77
|
-
|
|
78
|
-
before { @tx = @store.get_block_by_depth(1).tx[0] }
|
|
79
|
-
|
|
80
|
-
it "should get block" do
|
|
81
|
-
@tx.get_block.should == @store.get_block_by_depth(1)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
it "should get confirmations" do
|
|
85
|
-
@tx.confirmations.should == 3
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
it "should get total out" do
|
|
89
|
-
@tx.total_out.should == 5000000000
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
it "should get total in" do
|
|
93
|
-
@tx.total_in.should == 5000000000
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
it "should get fee" do
|
|
97
|
-
@tx.fee.should == 0
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
end
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
# encoding: ascii-8bit
|
|
2
|
-
|
|
3
|
-
require_relative '../spec_helper'
|
|
4
|
-
|
|
5
|
-
include Bitcoin::Builder
|
|
6
|
-
|
|
7
|
-
Bitcoin.network = :testnet
|
|
8
|
-
|
|
9
|
-
[
|
|
10
|
-
[:utxo, :sqlite, index_all_addrs: true],
|
|
11
|
-
[:sequel, :sqlite], # [:sequel, :postgres],
|
|
12
|
-
[:utxo, :postgres, index_all_addrs: true],
|
|
13
|
-
[:sequel, :mysql],
|
|
14
|
-
[:utxo, :mysql, index_all_addrs: true],
|
|
15
|
-
].compact.each do |options|
|
|
16
|
-
|
|
17
|
-
next unless storage = setup_db(*options)
|
|
18
|
-
|
|
19
|
-
describe "reorg (#{options[0]} - #{options[1]})" do
|
|
20
|
-
|
|
21
|
-
def balance addr
|
|
22
|
-
@store.get_balance(Bitcoin.hash160_from_address(addr))
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
before do
|
|
26
|
-
@store = storage
|
|
27
|
-
@store.reset
|
|
28
|
-
def @store.in_sync?; true; end
|
|
29
|
-
|
|
30
|
-
Bitcoin.network = :testnet
|
|
31
|
-
Bitcoin.network[:retarget_interval] = 10
|
|
32
|
-
Bitcoin.network[:proof_of_work_limit] = Bitcoin.encode_compact_bits("ff"*32)
|
|
33
|
-
|
|
34
|
-
@key = Bitcoin::Key.generate
|
|
35
|
-
@block0 = create_block "00"*32, false, [], @key
|
|
36
|
-
Bitcoin.network[:genesis_hash] = @block0.hash
|
|
37
|
-
|
|
38
|
-
@store.store_block(@block0)
|
|
39
|
-
@store.get_head.should == @block0
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it "should retarget" do
|
|
43
|
-
@store.reset
|
|
44
|
-
time = Time.now.to_i - 3000*600
|
|
45
|
-
|
|
46
|
-
# create genesis block
|
|
47
|
-
block = create_block "00"*32, false, [], @key, 50e8, {time: time}
|
|
48
|
-
Bitcoin.network[:genesis_hash] = block.hash
|
|
49
|
-
@store.store_block(block)
|
|
50
|
-
time += 600
|
|
51
|
-
|
|
52
|
-
# create too fast blocks
|
|
53
|
-
block = create_blocks block.hash, 9, time: time, interval: 10
|
|
54
|
-
time += 90
|
|
55
|
-
|
|
56
|
-
-> { create_blocks block.hash, 1, time: time }
|
|
57
|
-
.should.raise(Bitcoin::Validation::ValidationError).message.should =~ /difficulty/
|
|
58
|
-
|
|
59
|
-
block = create_blocks block.hash, 1, time: time, bits: bits = 541065152
|
|
60
|
-
@store.get_head.should == block
|
|
61
|
-
time += 600
|
|
62
|
-
|
|
63
|
-
# create too slow blocks
|
|
64
|
-
block = create_blocks block.hash, 9, time: time, interval: 6000, bits: bits
|
|
65
|
-
time += 8*6000
|
|
66
|
-
-> { create_blocks block.hash, 1, time: time, bits: bits }
|
|
67
|
-
.should.raise(Bitcoin::Validation::ValidationError).message.should =~ /difficulty/
|
|
68
|
-
|
|
69
|
-
block = create_blocks block.hash, 1, bits: 553713663
|
|
70
|
-
@store.get_head.should == block
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
it "should reorg across a retargetting boundary correctly" do
|
|
74
|
-
@store.reset
|
|
75
|
-
time = Time.now.to_i - 3000*600
|
|
76
|
-
|
|
77
|
-
# create genesis block
|
|
78
|
-
block = create_block "00"*32, false, [], @key, 50e8, {time: time}
|
|
79
|
-
time += 600
|
|
80
|
-
Bitcoin.network[:genesis_hash] = block.hash
|
|
81
|
-
@store.store_block(block)
|
|
82
|
-
|
|
83
|
-
# create first regular block
|
|
84
|
-
split_block = create_blocks block.hash, 1, time: time
|
|
85
|
-
split_time = time + 600
|
|
86
|
-
|
|
87
|
-
# create branch A with target interval
|
|
88
|
-
block_a = create_blocks split_block.hash, 8, time: split_time
|
|
89
|
-
time_a = split_time + 8 * 600
|
|
90
|
-
|
|
91
|
-
# create branch B with faster-than-target interval
|
|
92
|
-
block_b = create_blocks split_block.hash, 8, time: split_time, interval: 60
|
|
93
|
-
time_b = split_time + 8 * 60
|
|
94
|
-
|
|
95
|
-
# create 2 blocks for branch A with regular difficulty
|
|
96
|
-
block_a = create_blocks block_a.hash, 2, time: time_a
|
|
97
|
-
|
|
98
|
-
# create 1 block for branch B at higher difficulty
|
|
99
|
-
block_b = create_blocks block_b.hash, 1, time: time_b, bits: 541568460
|
|
100
|
-
|
|
101
|
-
# check that shorter branch B has overtaken longer branch A due to more work
|
|
102
|
-
@store.get_head.hash.should == block_b.hash
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
it "should validate duplicate tx in a side chain" do
|
|
106
|
-
block1 = create_block @block0.hash, true, [], @key
|
|
107
|
-
|
|
108
|
-
block_2_0 = create_block block1.hash, false, [ ->(t) {
|
|
109
|
-
t.input {|i| i.prev_out block1.tx[0], 0; i.signature_key @key }
|
|
110
|
-
t.output {|o| o.value 50e8; o.script {|s| s.recipient @key.addr } }
|
|
111
|
-
}], @key
|
|
112
|
-
|
|
113
|
-
@store.store_block(block_2_0).should == [2, 0]
|
|
114
|
-
|
|
115
|
-
block_3_0 = create_block block_2_0.hash, false, [->(t) {
|
|
116
|
-
t.input {|i| i.prev_out block_2_0.tx[1], 0; i.signature_key @key }
|
|
117
|
-
t.output {|o| o.value 50e8; o.script {|s| s.recipient @key.addr } }
|
|
118
|
-
}], @key
|
|
119
|
-
@store.store_block(block_3_0).should == [3, 0]
|
|
120
|
-
|
|
121
|
-
block_2_1 = create_block block1.hash, false
|
|
122
|
-
block_2_1.tx << block_2_0.tx[1]
|
|
123
|
-
block_2_1.recalc_mrkl_root
|
|
124
|
-
block_2_1.recalc_block_hash
|
|
125
|
-
@store.store_block(block_2_1).should == [2, 1]
|
|
126
|
-
|
|
127
|
-
block_3_1 = create_block block_2_1.hash, false
|
|
128
|
-
block_3_1.tx << block_3_0.tx[1]
|
|
129
|
-
block_3_1.recalc_mrkl_root
|
|
130
|
-
block_3_1.recalc_block_hash
|
|
131
|
-
|
|
132
|
-
@store.store_block(block_3_1).should == [3, 1]
|
|
133
|
-
|
|
134
|
-
block_4 = create_block block_3_1.hash, false
|
|
135
|
-
@store.store_block(block_4).should == [4, 0]
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
it "should reorg a single side block" do
|
|
139
|
-
@store.get_head.should == @block0
|
|
140
|
-
|
|
141
|
-
block1 = create_block @block0.hash
|
|
142
|
-
@store.get_head.should == block1
|
|
143
|
-
|
|
144
|
-
block2_0 = create_block block1.hash
|
|
145
|
-
@store.get_head.should == block2_0
|
|
146
|
-
|
|
147
|
-
block2_1 = create_block block1.hash
|
|
148
|
-
@store.get_head.should == block2_0
|
|
149
|
-
|
|
150
|
-
block3 = create_block block2_1.hash
|
|
151
|
-
@store.get_head.should == block3
|
|
152
|
-
@store.get_block_by_depth(2).hash.should == block2_1.hash
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
it "should reorg two side blocks" do
|
|
156
|
-
block1 = create_block @block0.hash
|
|
157
|
-
@store.get_head.should == block1
|
|
158
|
-
|
|
159
|
-
block2_0 = create_block block1.hash
|
|
160
|
-
@store.get_head.should == block2_0
|
|
161
|
-
|
|
162
|
-
block2_1 = create_block block1.hash
|
|
163
|
-
@store.get_head.should == block2_0
|
|
164
|
-
|
|
165
|
-
block3_1 = create_block block2_1.hash
|
|
166
|
-
@store.get_head.should == block3_1
|
|
167
|
-
|
|
168
|
-
block3_0 = create_block block2_0.hash
|
|
169
|
-
@store.get_head.should == block3_1
|
|
170
|
-
|
|
171
|
-
block4 = create_block block3_0.hash
|
|
172
|
-
@store.get_head.should == block4
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
it "should reconnect orphans" do
|
|
176
|
-
next(true.should == true) if @store.class.name =~ /Utxo/
|
|
177
|
-
blocks = [@block0]
|
|
178
|
-
3.times { blocks << create_block(blocks.last.hash, false) }
|
|
179
|
-
|
|
180
|
-
{
|
|
181
|
-
[0, 1, 2, 3] => [0, 1, 2, 3],
|
|
182
|
-
[0, 1, 3, 2] => [0, 1, 1, 3],
|
|
183
|
-
[0, 3, 2, 1] => [0, 0, 0, 3],
|
|
184
|
-
[0, 3, 1, 2] => [0, 0, 1, 3],
|
|
185
|
-
[0, 2, 3, 1] => [0, 0, 0, 3],
|
|
186
|
-
}.each do |order, result|
|
|
187
|
-
@store.reset
|
|
188
|
-
order.each_with_index do |n, i|
|
|
189
|
-
@store.store_block(blocks[n])
|
|
190
|
-
@store.get_head.should == blocks[result[i]]
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
i = 3; (0..i).to_a.permutation.each do |order|
|
|
195
|
-
@store.reset
|
|
196
|
-
order.each {|n| @store.store_block(blocks[n]) }
|
|
197
|
-
@store.get_head.should == blocks[i]
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
it "should handle existing blocks" do
|
|
202
|
-
blocks = [@block0]
|
|
203
|
-
3.times { blocks << create_block(blocks.last.hash, false) }
|
|
204
|
-
blocks[1..-1].each.with_index {|b, idx| @store.store_block(b).should == [idx+1, 0] }
|
|
205
|
-
3.times {|i| @store.store_block(blocks[i]).should == [i] }
|
|
206
|
-
@store.get_head.should == blocks[-1]
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
# see https://bitcointalk.org/index.php?topic=46370.0
|
|
210
|
-
it "should pass reorg unit tests" do
|
|
211
|
-
Bitcoin.network = :bitcoin
|
|
212
|
-
# Disable difficulty check
|
|
213
|
-
Bitcoin.network[:no_difficulty] = true
|
|
214
|
-
@store.import "./spec/bitcoin/fixtures/reorg/blk_0_to_4.dat"
|
|
215
|
-
@store.get_depth.should == 4
|
|
216
|
-
@store.get_head.hash.should =~ /000000002f264d65040/
|
|
217
|
-
balance("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa").should == 10000000000
|
|
218
|
-
balance("1NiEGXeURREqqMjCvjCeZn6SwEBZ9AdVet").should == 0
|
|
219
|
-
balance("1KXFNhNtrRMfgbdiQeuJqnfD7dR4PhniyJ").should == 5000000000
|
|
220
|
-
balance("1JyMKvPHkrCQd8jQrqTR1rBsAd1VpRhTiE").should == 10000000000
|
|
221
|
-
@store.import "./spec/bitcoin/fixtures/reorg/blk_3A.dat"
|
|
222
|
-
@store.import "./spec/bitcoin/fixtures/reorg/blk_4A.dat"
|
|
223
|
-
@store.get_head.hash.should =~ /000000002f264d65040/
|
|
224
|
-
@store.import "./spec/bitcoin/fixtures/reorg/blk_5A.dat"
|
|
225
|
-
@store.get_depth.should == 5
|
|
226
|
-
@store.get_head.hash.should =~ /00000000195f85184e7/
|
|
227
|
-
balance("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa").should == 15000000000
|
|
228
|
-
balance("1NiEGXeURREqqMjCvjCeZn6SwEBZ9AdVet").should == 1000000000
|
|
229
|
-
balance("1KXFNhNtrRMfgbdiQeuJqnfD7dR4PhniyJ").should == 0
|
|
230
|
-
balance("1JyMKvPHkrCQd8jQrqTR1rBsAd1VpRhTiE").should == 14000000000
|
|
231
|
-
Bitcoin.network.delete :no_difficulty
|
|
232
|
-
Bitcoin.network = :testnet
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
end
|
|
236
|
-
end
|
|
@@ -1,387 +0,0 @@
|
|
|
1
|
-
# encoding: ascii-8bit
|
|
2
|
-
|
|
3
|
-
require_relative '../spec_helper'
|
|
4
|
-
|
|
5
|
-
include Bitcoin
|
|
6
|
-
include Bitcoin::Storage
|
|
7
|
-
include Bitcoin::Storage::Backends
|
|
8
|
-
include Bitcoin::Builder
|
|
9
|
-
include Bitcoin::Validation
|
|
10
|
-
|
|
11
|
-
Bitcoin::network = :testnet
|
|
12
|
-
[
|
|
13
|
-
[:dummy],
|
|
14
|
-
[:sequel, :sqlite],
|
|
15
|
-
[:utxo, :sqlite, index_all_addrs: true],
|
|
16
|
-
[:sequel, :postgres],
|
|
17
|
-
[:utxo, :postgres, index_all_addrs: true],
|
|
18
|
-
[:sequel, :mysql],
|
|
19
|
-
[:utxo, :mysql, index_all_addrs: true],
|
|
20
|
-
].compact.each do |options|
|
|
21
|
-
|
|
22
|
-
next unless storage = setup_db(*options)
|
|
23
|
-
|
|
24
|
-
describe "Storage::Backends::#{options[0].to_s.capitalize}Store (#{options[1]})" do
|
|
25
|
-
|
|
26
|
-
before do
|
|
27
|
-
Bitcoin.network[:no_difficulty] = true
|
|
28
|
-
Bitcoin.network[:proof_of_work_limit] = Bitcoin.encode_compact_bits("ff"*32)
|
|
29
|
-
|
|
30
|
-
@store = storage
|
|
31
|
-
def @store.in_sync?; true; end
|
|
32
|
-
@store.reset
|
|
33
|
-
|
|
34
|
-
@store.store_block(P::Block.new(fixtures_file('testnet/block_0.bin')))
|
|
35
|
-
@store.store_block(P::Block.new(fixtures_file('testnet/block_1.bin')))
|
|
36
|
-
@store.store_block(P::Block.new(fixtures_file('testnet/block_2.bin')))
|
|
37
|
-
@store.store_block(P::Block.new(fixtures_file('testnet/block_3.bin')))
|
|
38
|
-
|
|
39
|
-
unless @store.class.name =~ /UtxoStore/
|
|
40
|
-
@store.store_tx(P::Tx.new(fixtures_file('rawtx-01.bin')), false)
|
|
41
|
-
@store.store_tx(P::Tx.new(fixtures_file('rawtx-02.bin')), false)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
@blk = P::Block.new(fixtures_file('testnet/block_4.bin'))
|
|
45
|
-
@tx = P::Tx.new(fixtures_file('rawtx-03.bin'))
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
after do
|
|
49
|
-
Bitcoin.network.delete :no_difficulty
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it "should get backend name" do
|
|
53
|
-
@store.backend_name.should == options[0].to_s
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "should get depth" do
|
|
57
|
-
@store.get_depth.should == 3
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
it "should report depth as -1 if store is empty" do
|
|
61
|
-
@store.reset
|
|
62
|
-
@store.get_depth.should == -1
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it "should get head" do
|
|
66
|
-
@store.get_head
|
|
67
|
-
.should == @store.get_block("0000000098932356a236718829dd9e3eb0f9143317ab921333b1a203de336de4")
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
it "should get locator" do
|
|
71
|
-
@store.get_locator.should == [
|
|
72
|
-
"0000000098932356a236718829dd9e3eb0f9143317ab921333b1a203de336de4",
|
|
73
|
-
"000000037b21cac5d30fc6fda2581cf7b2612908aed2abbcc429c45b0557a15f",
|
|
74
|
-
"000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604",
|
|
75
|
-
"00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008"]
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
it "should not store if there is no prev block" do
|
|
79
|
-
@store.reset
|
|
80
|
-
@store.store_block(@blk).should == [0, 2]
|
|
81
|
-
@store.get_depth.should == -1
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
it "should check whether block is already stored" do
|
|
85
|
-
@store.has_block(@blk.hash).should == false
|
|
86
|
-
@store.store_block(@blk)
|
|
87
|
-
@store.has_block(@blk.hash).should == true
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
it "should get block by depth" do
|
|
91
|
-
@store.get_block_by_depth(0).hash.should ==
|
|
92
|
-
P::Block.new(fixtures_file('testnet/block_0.bin')).hash
|
|
93
|
-
@store.get_block_by_depth(1).hash.should ==
|
|
94
|
-
P::Block.new(fixtures_file('testnet/block_1.bin')).hash
|
|
95
|
-
@store.get_block_by_depth(2).hash.should ==
|
|
96
|
-
P::Block.new(fixtures_file('testnet/block_2.bin')).hash
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
it "should store and retrieve all relevant block data for hash/json serialization" do
|
|
100
|
-
(0..2).each do |i|
|
|
101
|
-
expected = P::Block.new(fixtures_file("testnet/block_#{i}.bin")).to_hash
|
|
102
|
-
@store.get_block_by_depth(i).to_hash.should == expected
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
it "should get block by hash" do
|
|
107
|
-
@store.get_block(
|
|
108
|
-
"00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008").hash
|
|
109
|
-
.should == P::Block.new(fixtures_file('testnet/block_0.bin')).hash
|
|
110
|
-
@store.get_block(
|
|
111
|
-
"000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604").hash
|
|
112
|
-
.should == P::Block.new(fixtures_file('testnet/block_1.bin')).hash
|
|
113
|
-
@store.get_block(
|
|
114
|
-
"000000037b21cac5d30fc6fda2581cf7b2612908aed2abbcc429c45b0557a15f").hash
|
|
115
|
-
.should == P::Block.new(fixtures_file('testnet/block_2.bin')).hash
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
it "should not get block" do
|
|
119
|
-
@store.get_block("nonexistant").should == nil
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
it "should get block depth" do
|
|
123
|
-
@store.get_block("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")
|
|
124
|
-
.depth.should == 0
|
|
125
|
-
@store.get_block("000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604")
|
|
126
|
-
.depth.should == 1
|
|
127
|
-
@store.get_block("000000037b21cac5d30fc6fda2581cf7b2612908aed2abbcc429c45b0557a15f")
|
|
128
|
-
.depth.should == 2
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
it "should get prev block" do
|
|
132
|
-
@store.get_block("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")
|
|
133
|
-
.get_prev_block.should == nil
|
|
134
|
-
@store.get_block("000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604")
|
|
135
|
-
.get_prev_block.should ==
|
|
136
|
-
@store.get_block("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
it "should get next block" do
|
|
140
|
-
@store.get_block("0000000098932356a236718829dd9e3eb0f9143317ab921333b1a203de336de4")
|
|
141
|
-
.get_next_block.should == nil
|
|
142
|
-
@store.get_block("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")
|
|
143
|
-
.get_next_block.should ==
|
|
144
|
-
@store.get_block("000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604")
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
it "should get block for tx" do
|
|
148
|
-
@store.store_block(@blk)
|
|
149
|
-
@store.get_block_by_tx(@blk.tx[0].hash).should == @blk
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
it "should get block id for tx id" do
|
|
153
|
-
@store.store_block(@blk)
|
|
154
|
-
tx = @store.get_tx(@blk.tx[0].hash)
|
|
155
|
-
@store.get_block_id_for_tx_id(tx.id).should == @store.get_block(@blk.hash).id
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
unless @store.backend_name == 'utxo'
|
|
159
|
-
describe :transactions do
|
|
160
|
-
|
|
161
|
-
it "should store tx" do
|
|
162
|
-
@store.store_tx(@tx, false).should != false
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
it "should not store tx if already stored and return existing id" do
|
|
166
|
-
id = @store.store_tx(@tx, false)
|
|
167
|
-
@store.store_tx(@tx, false).should == id
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
it "should check if tx is already stored" do
|
|
171
|
-
@store.has_tx(@tx.hash).should == false
|
|
172
|
-
@store.store_tx(@tx, false)
|
|
173
|
-
@store.has_tx(@tx.hash).should == true
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
it "should store hash160 for txout" do
|
|
177
|
-
@store.store_tx(@tx, false)
|
|
178
|
-
@store.get_tx(@tx.hash).out[0].hash160
|
|
179
|
-
.should == "3129d7051d509424d23d533fa2d5258977e822e3"
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
it "should get tx" do
|
|
183
|
-
@store.store_tx(@tx, false)
|
|
184
|
-
@store.get_tx(@tx.hash).should == @tx
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
it "should not get tx" do
|
|
188
|
-
@store.get_tx("nonexistant").should == nil
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
it "should get the position for a given tx" do
|
|
192
|
-
@store.store_block(@blk)
|
|
193
|
-
result = @store.get_idx_from_tx_hash(@blk.tx[0].hash)
|
|
194
|
-
result.should == 0
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
it "should get tx for txin" do
|
|
198
|
-
@store.store_tx(@tx, false)
|
|
199
|
-
@store.get_tx(@tx.hash).in[0].get_tx.should == @tx
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
it "should get prev out for txin" do
|
|
203
|
-
tx = P::Tx.new(fixtures_file('rawtx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.bin'))
|
|
204
|
-
outpoint_tx = P::Tx.new(fixtures_file('rawtx-0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9.bin'))
|
|
205
|
-
@store.store_tx(outpoint_tx, false)
|
|
206
|
-
@store.store_tx(tx, false)
|
|
207
|
-
@store.get_tx(tx.hash).in[0].get_prev_out.should == outpoint_tx.out[0]
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
it "should get tx for txout" do
|
|
211
|
-
@store.store_tx(@tx, false)
|
|
212
|
-
@store.get_tx(@tx.hash).out[0].get_tx.should == @tx
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
it "should get next in for txin" do
|
|
216
|
-
tx = P::Tx.new(fixtures_file('rawtx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.bin'))
|
|
217
|
-
outpoint_tx = P::Tx.new(fixtures_file('rawtx-0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9.bin'))
|
|
218
|
-
@store.store_tx(outpoint_tx, false)
|
|
219
|
-
@store.store_tx(tx, false)
|
|
220
|
-
@store.get_tx(outpoint_tx.hash).out[0].get_next_in.should == tx.in[0]
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
it "should store multisig tx and index hash160's" do
|
|
224
|
-
keys = Array.new(2) { Bitcoin::Key.generate }
|
|
225
|
-
pk_script = Bitcoin::Script.to_multisig_script(1, keys[0].pub, keys[1].pub)
|
|
226
|
-
txout = P::TxOut.new(1000, pk_script)
|
|
227
|
-
@tx.out[0] = txout
|
|
228
|
-
@store.store_tx(@tx, false)
|
|
229
|
-
keys.each do |key|
|
|
230
|
-
hash160 = Bitcoin.hash160(key.pub)
|
|
231
|
-
txouts = @store.get_txouts_for_hash160(hash160, :hash160, true)
|
|
232
|
-
txouts.size.should == 1
|
|
233
|
-
txouts[0].pk_script.should == txout.pk_script
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
it "should index output script type" do
|
|
238
|
-
@store.store_tx(@tx, false)
|
|
239
|
-
@store.get_tx(@tx.hash).out.first.type.should == :hash160
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
end
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
describe :txouts do
|
|
247
|
-
|
|
248
|
-
before do
|
|
249
|
-
@key = Key.generate
|
|
250
|
-
@key2 = Key.generate
|
|
251
|
-
@store.store_block(@blk)
|
|
252
|
-
blk = create_block @blk.hash, true, [], @key
|
|
253
|
-
@block = create_block blk.hash, true, [->(t) {
|
|
254
|
-
create_tx(t, blk.tx.first, 0, [[50, @key2]]) }], @key
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
it "should get block for tx" do
|
|
258
|
-
@store.get_tx(@block.tx[1].hash).get_block.hash.should == @block.hash
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
it "should get txouts for pk script" do
|
|
262
|
-
script = @blk.tx[0].out[0].pk_script
|
|
263
|
-
@store.get_txouts_for_pk_script(script)
|
|
264
|
-
.should == [@blk.tx[0].out[0]]
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
it "should get txouts for hash160" do
|
|
268
|
-
@store.get_txouts_for_hash160(@key2.hash160, :hash160, true)
|
|
269
|
-
.should == [@block.tx[1].out[0]]
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
it "should get txouts for address" do
|
|
273
|
-
@store.get_txouts_for_address(@key2.addr, true)
|
|
274
|
-
.should == [@block.tx[1].out[0]]
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
it "should get txouts for txin" do
|
|
278
|
-
prev_tx = @block.tx[0]
|
|
279
|
-
tx = build_tx { |t| create_tx(t, prev_tx, 0, [[prev_tx.out[0].value, Bitcoin::Key.generate]], @key) }
|
|
280
|
-
@store.get_txout_for_txin(tx.in[0]).should == prev_tx.out[0]
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
it "should get unspent txouts for address" do
|
|
284
|
-
@store.get_unspent_txouts_for_address(@key2.addr, true)
|
|
285
|
-
.should == [@block.tx[1].out[0]]
|
|
286
|
-
@block2 = create_block @block.hash, true, [->(t) {
|
|
287
|
-
create_tx(t, @block.tx[1], 0, [[20, @key2]], @key2) }], @key
|
|
288
|
-
@store.get_unspent_txouts_for_address(@key2.addr, true)
|
|
289
|
-
.should == [@block2.tx[1].out[0]]
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
it "should get balance for address" do
|
|
293
|
-
@store.get_balance(@key2.addr).should == 50
|
|
294
|
-
@store.get_balance(@key2.hash160).should == 50
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
it "should get txouts for p2sh address (and not confuse regular and p2sh-type hash160" do
|
|
298
|
-
block = create_block(@block.hash, false, [], @key)
|
|
299
|
-
|
|
300
|
-
tx = build_tx do |t|
|
|
301
|
-
t.input {|i| i.prev_out(@block.tx[1], 0); i.signature_key(@key2) }
|
|
302
|
-
t.output do |o|
|
|
303
|
-
o.value 10
|
|
304
|
-
o.to @key2.hash160, :p2sh
|
|
305
|
-
end
|
|
306
|
-
t.output do |o|
|
|
307
|
-
o.value 10
|
|
308
|
-
o.to @key2.addr
|
|
309
|
-
end
|
|
310
|
-
end
|
|
311
|
-
block.tx << tx; block.recalc_mrkl_root; block.recalc_block_hash
|
|
312
|
-
|
|
313
|
-
@store.store_block(block)
|
|
314
|
-
|
|
315
|
-
p2sh_address = Bitcoin.hash160_to_p2sh_address(@key2.hash160)
|
|
316
|
-
o1 = @store.get_unspent_txouts_for_address(@key2.addr)
|
|
317
|
-
o2 = @store.get_unspent_txouts_for_address(p2sh_address)
|
|
318
|
-
|
|
319
|
-
o1.size.should == 1
|
|
320
|
-
o2.size.should == 1
|
|
321
|
-
o1.should != o2
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
describe "validation" do
|
|
327
|
-
|
|
328
|
-
before do
|
|
329
|
-
@key = Bitcoin::Key.generate
|
|
330
|
-
@store.store_block @blk
|
|
331
|
-
@block = create_block @blk.hash, false, [], @key
|
|
332
|
-
@tx = build_tx {|t| create_tx(t, @block.tx.first, 0, [[50, @key]]) }
|
|
333
|
-
@tx.instance_eval { @in = [] }
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
it "should validate blocks" do
|
|
337
|
-
@block.tx << @tx
|
|
338
|
-
-> { @store.store_block(@block) }.should
|
|
339
|
-
.raise(ValidationError).message.should =~ /mrkl_root/
|
|
340
|
-
end
|
|
341
|
-
|
|
342
|
-
it "should validate transactions for blocks added to main chain" do
|
|
343
|
-
@store.store_block(@block)
|
|
344
|
-
block = create_block @block.hash, false, [->(tx) {
|
|
345
|
-
create_tx(tx, @block.tx.first, 0, [[50, @key]]) }], @key
|
|
346
|
-
block.tx.last.in[0].prev_out_index = 5
|
|
347
|
-
-> { @store.store_block(block) }.should
|
|
348
|
-
.raise(ValidationError).message.should =~ /transactions_syntax/
|
|
349
|
-
end
|
|
350
|
-
|
|
351
|
-
it "should not validate transactions for blocks added to a side or orphan chain" do
|
|
352
|
-
@store.store_block(@block)
|
|
353
|
-
block = create_block @blk.hash, false, [->(tx) {
|
|
354
|
-
create_tx(tx, @block.tx.first, 0, [[50, @key]]) }], @key
|
|
355
|
-
@store.store_block(block).should == [5, 1]
|
|
356
|
-
end
|
|
357
|
-
|
|
358
|
-
if @store.class.name =~ /Sequel/
|
|
359
|
-
|
|
360
|
-
it "should validate transactions" do
|
|
361
|
-
@store.store_block @block
|
|
362
|
-
-> { @store.store_tx(@tx, true) }.should.raise(ValidationError)
|
|
363
|
-
end
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
it "should validate transactions for new main blocks on reorg" do
|
|
367
|
-
@store.store_block(@block)
|
|
368
|
-
block = create_block @blk.hash, true, [->(tx) {
|
|
369
|
-
create_tx(tx, @block.tx.first, 0, [[50, @key]]) }], @key
|
|
370
|
-
block2 = create_block block.hash, false, [], @key
|
|
371
|
-
-> { @store.store_block(block2) }.should
|
|
372
|
-
.raise(ValidationError).message.should =~ /transactions_context/
|
|
373
|
-
end
|
|
374
|
-
|
|
375
|
-
end
|
|
376
|
-
|
|
377
|
-
it "should skip validation" do
|
|
378
|
-
@store.config[:skip_validation] = true
|
|
379
|
-
@block.tx << @tx
|
|
380
|
-
@store.store_block(@block).should == [5, 0]
|
|
381
|
-
end
|
|
382
|
-
|
|
383
|
-
end
|
|
384
|
-
|
|
385
|
-
end
|
|
386
|
-
|
|
387
|
-
end
|