bitcoinrb 1.12.0 → 1.13.0
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/.github/workflows/ruby.yml +1 -1
- data/bitcoinrb.gemspec +1 -6
- data/lib/bitcoin/bip321_uri.rb +3 -6
- data/lib/bitcoin/bip324/fs_chacha20.rb +4 -6
- data/lib/bitcoin/bip324/fs_chacha_poly1305.rb +20 -17
- data/lib/bitcoin/bip324.rb +3 -1
- data/lib/bitcoin/descriptor/checksum.rb +6 -2
- data/lib/bitcoin/descriptor/expression.rb +2 -2
- data/lib/bitcoin/descriptor/sp.rb +219 -0
- data/lib/bitcoin/descriptor.rb +20 -0
- data/lib/bitcoin/ext_key.rb +11 -7
- data/lib/bitcoin/key.rb +1 -1
- data/lib/bitcoin/message/cf_parser.rb +2 -2
- data/lib/bitcoin/message/fee_filter.rb +2 -2
- data/lib/bitcoin/message/header_and_short_ids.rb +4 -4
- data/lib/bitcoin/message/inventory.rb +1 -1
- data/lib/bitcoin/message/network_addr.rb +7 -3
- data/lib/bitcoin/message/ping.rb +5 -3
- data/lib/bitcoin/message/pong.rb +2 -2
- data/lib/bitcoin/message/send_cmpct.rb +2 -2
- data/lib/bitcoin/message/version.rb +4 -4
- data/lib/bitcoin/message.rb +12 -2
- data/lib/bitcoin/message_sign.rb +98 -38
- data/lib/bitcoin/mnemonic.rb +9 -4
- data/lib/bitcoin/psbt/input.rb +51 -33
- data/lib/bitcoin/psbt/key_origin_info.rb +2 -2
- data/lib/bitcoin/psbt/output.rb +9 -5
- data/lib/bitcoin/psbt/tx.rb +16 -10
- data/lib/bitcoin/psbt.rb +1 -1
- data/lib/bitcoin/rpc.rb +0 -2
- data/lib/bitcoin/script/script.rb +14 -4
- data/lib/bitcoin/secp256k1/rfc6979.rb +6 -3
- data/lib/bitcoin/sighash_generator.rb +2 -2
- data/lib/bitcoin/silent_payment/output.rb +46 -0
- data/lib/bitcoin/silent_payment.rb +113 -12
- data/lib/bitcoin/taproot/control_block.rb +1 -0
- data/lib/bitcoin/tx.rb +8 -6
- data/lib/bitcoin/tx_out.rb +2 -2
- data/lib/bitcoin/util.rb +5 -5
- data/lib/bitcoin/version.rb +1 -1
- data/lib/bitcoin/wallet/account.rb +2 -2
- data/lib/bitcoin/wallet/db.rb +3 -3
- data/lib/bitcoin/wallet/master_key.rb +2 -2
- data/lib/bitcoin/wallet/utxo.rb +2 -2
- data/lib/bitcoin.rb +1 -6
- metadata +18 -108
- data/exe/bitcoinrb-cli +0 -5
- data/exe/bitcoinrbd +0 -46
- data/lib/bitcoin/network/connection.rb +0 -73
- data/lib/bitcoin/network/message_handler.rb +0 -243
- data/lib/bitcoin/network/peer.rb +0 -228
- data/lib/bitcoin/network/peer_discovery.rb +0 -42
- data/lib/bitcoin/network/pool.rb +0 -135
- data/lib/bitcoin/network.rb +0 -13
- data/lib/bitcoin/node/cli.rb +0 -122
- data/lib/bitcoin/node/configuration.rb +0 -40
- data/lib/bitcoin/node/spv.rb +0 -87
- data/lib/bitcoin/node.rb +0 -7
- data/lib/bitcoin/rpc/http_server.rb +0 -84
- data/lib/bitcoin/rpc/request_handler.rb +0 -150
- data/lib/bitcoin/store/chain_entry.rb +0 -68
- data/lib/bitcoin/store/db/level_db.rb +0 -98
- data/lib/bitcoin/store/db.rb +0 -9
- data/lib/bitcoin/store/spv_chain.rb +0 -101
- data/lib/bitcoin/store/utxo_db.rb +0 -226
- data/lib/bitcoin/store.rb +0 -12
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
require 'leveldb-native'
|
|
2
|
-
|
|
3
|
-
module Bitcoin
|
|
4
|
-
module Store
|
|
5
|
-
class UtxoDB
|
|
6
|
-
|
|
7
|
-
KEY_PREFIX = {
|
|
8
|
-
out_point: 'o', # key: out_point(tx_hash and index), value: Utxo
|
|
9
|
-
script: 's', # key: script_pubkey and out_point(tx_hash and index), value: Utxo
|
|
10
|
-
height: 'h', # key: block_height and out_point, value: Utxo
|
|
11
|
-
tx_hash: 't', # key: tx_hash of transaction, value: [block_height, tx_index]
|
|
12
|
-
block: 'b', # key: block_height and tx_index, value: tx_hash
|
|
13
|
-
tx_payload: 'p', # key: tx_hash, value: Tx
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
attr_reader :level_db, :logger
|
|
17
|
-
|
|
18
|
-
def initialize(path = "#{Bitcoin.base_dir}/db/utxo")
|
|
19
|
-
FileUtils.mkdir_p(path)
|
|
20
|
-
@level_db = ::LevelDBNative::DB.new(path)
|
|
21
|
-
@logger = Bitcoin::Logger.create(:debug)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def close
|
|
25
|
-
level_db.close
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Save payload of a transaction into db
|
|
29
|
-
#
|
|
30
|
-
# @param [String] tx_hash
|
|
31
|
-
# @param [String] tx_payload
|
|
32
|
-
def save_tx(tx_hash, tx_payload)
|
|
33
|
-
logger.info("UtxoDB#save_tx:#{[tx_hash, tx_payload]}")
|
|
34
|
-
level_db.batch do
|
|
35
|
-
# tx_hash -> [block_height, tx_index]
|
|
36
|
-
key = KEY_PREFIX[:tx_payload] + tx_hash
|
|
37
|
-
level_db.put(key, tx_payload)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Save tx position (block height and index in the block) into db
|
|
42
|
-
# When node receives `header` message, node should call save_tx_position to store block height and its index.
|
|
43
|
-
#
|
|
44
|
-
# @param [String] tx_hash
|
|
45
|
-
# @param [Integer] block_height
|
|
46
|
-
# @param [Integer] tx_index
|
|
47
|
-
def save_tx_position(tx_hash, block_height, tx_index)
|
|
48
|
-
logger.info("UtxoDB#save_tx_position:#{[tx_hash, block_height, tx_index]}")
|
|
49
|
-
level_db.batch do
|
|
50
|
-
# tx_hash -> [block_height, tx_index]
|
|
51
|
-
key = KEY_PREFIX[:tx_hash] + tx_hash
|
|
52
|
-
level_db.put(key, [block_height, tx_index].pack('N2').bth)
|
|
53
|
-
|
|
54
|
-
# block_hash and tx_index -> tx_hash
|
|
55
|
-
key = KEY_PREFIX[:block] + [block_height, tx_index].pack('N2').bth
|
|
56
|
-
level_db.put(key, tx_hash)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# Save utxo into db
|
|
61
|
-
#
|
|
62
|
-
# @param [Bitcoin::OutPoint] out_point
|
|
63
|
-
# @param [Double] value
|
|
64
|
-
# @param [Bitcoin::Script] script_pubkey
|
|
65
|
-
# @param [Integer] block_height
|
|
66
|
-
def save_utxo(out_point, value, script_pubkey, block_height=nil)
|
|
67
|
-
logger.info("UtxoDB#save_utxo:#{[out_point, value, script_pubkey, block_height]}")
|
|
68
|
-
level_db.batch do
|
|
69
|
-
utxo = Bitcoin::Wallet::Utxo.new(out_point.tx_hash, out_point.index, value, script_pubkey, block_height)
|
|
70
|
-
payload = utxo.to_payload
|
|
71
|
-
|
|
72
|
-
# out_point
|
|
73
|
-
key = KEY_PREFIX[:out_point] + out_point.to_hex
|
|
74
|
-
return if level_db.contains?(key)
|
|
75
|
-
level_db.put(key, payload)
|
|
76
|
-
|
|
77
|
-
# script_pubkey
|
|
78
|
-
if script_pubkey
|
|
79
|
-
key = KEY_PREFIX[:script] + script_pubkey.to_hex + out_point.to_hex
|
|
80
|
-
level_db.put(key, payload)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# height
|
|
84
|
-
unless block_height.nil?
|
|
85
|
-
key = KEY_PREFIX[:height] + [block_height].pack('N').bth + out_point.to_hex
|
|
86
|
-
level_db.put(key, payload)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
utxo
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Get transaction stored via save_tx and save_tx_position
|
|
94
|
-
#
|
|
95
|
-
# @param [string] tx_hash
|
|
96
|
-
# @return [block_height, tx_index, tx_payload]
|
|
97
|
-
def get_tx(tx_hash)
|
|
98
|
-
key = KEY_PREFIX[:tx_hash] + tx_hash
|
|
99
|
-
return [] unless level_db.contains?(key)
|
|
100
|
-
block_height, tx_index = level_db.get(key).htb.unpack('N2')
|
|
101
|
-
key = KEY_PREFIX[:tx_payload] + tx_hash
|
|
102
|
-
tx_payload = level_db.get(key)
|
|
103
|
-
[block_height, tx_index, tx_payload]
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# Delete utxo from db
|
|
107
|
-
#
|
|
108
|
-
# @param [Bitcoin::Outpoint] out_point
|
|
109
|
-
# @return [Bitcoin::Wallet::Utxo]
|
|
110
|
-
def delete_utxo(out_point)
|
|
111
|
-
level_db.batch do
|
|
112
|
-
# [:out_point]
|
|
113
|
-
key = KEY_PREFIX[:out_point] + out_point.to_hex
|
|
114
|
-
return unless level_db.contains?(key)
|
|
115
|
-
utxo = Bitcoin::Wallet::Utxo.parse_from_payload(level_db.get(key))
|
|
116
|
-
level_db.delete(key)
|
|
117
|
-
|
|
118
|
-
# [:script]
|
|
119
|
-
if utxo.script_pubkey
|
|
120
|
-
key = KEY_PREFIX[:script] + utxo.script_pubkey.to_hex + out_point.to_hex
|
|
121
|
-
level_db.delete(key)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
if utxo.block_height
|
|
125
|
-
# [:height]
|
|
126
|
-
key = KEY_PREFIX[:height] + [utxo.block_height].pack('N').bth + out_point.to_hex
|
|
127
|
-
level_db.delete(key)
|
|
128
|
-
|
|
129
|
-
# [:block]
|
|
130
|
-
key = KEY_PREFIX[:block] + [utxo.block_height, utxo.index].pack('N2').bth
|
|
131
|
-
level_db.delete(key)
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
# handles both [:tx_hash] and [:tx_payload]
|
|
135
|
-
if utxo.tx_hash
|
|
136
|
-
key = KEY_PREFIX[:tx_hash] + utxo.tx_hash
|
|
137
|
-
level_db.delete(key)
|
|
138
|
-
|
|
139
|
-
key = KEY_PREFIX[:tx_payload] + utxo.tx_hash
|
|
140
|
-
level_db.delete(key)
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
utxo
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# Get utxo of the specified out point
|
|
148
|
-
#
|
|
149
|
-
# @param [Bitcoin::Outpoint] out_point
|
|
150
|
-
# @return [Bitcoin::Wallet::Utxo]
|
|
151
|
-
def get_utxo(out_point)
|
|
152
|
-
level_db.batch do
|
|
153
|
-
key = KEY_PREFIX[:out_point] + out_point.to_hex
|
|
154
|
-
return unless level_db.contains?(key)
|
|
155
|
-
return Bitcoin::Wallet::Utxo.parse_from_payload(level_db.get(key))
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
# return [Bitcoin::Wallet::Utxo ...]
|
|
160
|
-
def list_unspent(current_block_height: 9999999, min: 0, max: 9999999, addresses: nil)
|
|
161
|
-
if addresses
|
|
162
|
-
list_unspent_by_addresses(current_block_height, min: min, max: max, addresses: addresses)
|
|
163
|
-
else
|
|
164
|
-
list_unspent_by_block_height(current_block_height, min: min, max: max)
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
# @param [Bitcoin::Wallet::Account]
|
|
169
|
-
# return [Bitcoin::Wallet::Utxo ...]
|
|
170
|
-
def list_unspent_in_account(account, current_block_height: 9999999, min: 0, max: 9999999)
|
|
171
|
-
return [] unless account
|
|
172
|
-
|
|
173
|
-
script_pubkeys = case account.purpose
|
|
174
|
-
when Bitcoin::Wallet::Account::PURPOSE_TYPE[:legacy]
|
|
175
|
-
account.watch_targets.map { |t| Bitcoin::Script.to_p2pkh(t).to_hex }
|
|
176
|
-
when Bitcoin::Wallet::Account::PURPOSE_TYPE[:nested_witness]
|
|
177
|
-
account.watch_targets.map { |t| Bitcoin::Script.to_p2wpkh(t).to_p2sh.to_hex }
|
|
178
|
-
when Bitcoin::Wallet::Account::PURPOSE_TYPE[:native_segwit]
|
|
179
|
-
account.watch_targets.map { |t| Bitcoin::Script.to_p2wpkh(t).to_hex }
|
|
180
|
-
end
|
|
181
|
-
list_unspent_by_script_pubkeys(current_block_height, min: min, max: max, script_pubkeys: script_pubkeys)
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
# @param [Bitcoin::Wallet::Account]
|
|
185
|
-
# return [Bitcoin::Wallet::Utxo ...]
|
|
186
|
-
def get_balance(account, current_block_height: 9999999, min: 0, max: 9999999)
|
|
187
|
-
list_unspent_in_account(account, current_block_height: current_block_height, min: min, max: max).sum { |u| u.value }
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
private
|
|
191
|
-
|
|
192
|
-
def utxos_between(from, to)
|
|
193
|
-
level_db.each(from: from, to: to).map { |k, v| Bitcoin::Wallet::Utxo.parse_from_payload(v) }
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
class ::Array
|
|
197
|
-
def with_height(min, max)
|
|
198
|
-
select { |u| u.block_height >= min && u.block_height <= max }
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
def list_unspent_by_block_height(current_block_height, min: 0, max: 9999999)
|
|
203
|
-
max_height = [current_block_height - min, 0].max
|
|
204
|
-
min_height = [current_block_height - max, 0].max
|
|
205
|
-
from = KEY_PREFIX[:height] + [min_height].pack('N').bth + '000000000000000000000000000000000000000000000000000000000000000000000000'
|
|
206
|
-
to = KEY_PREFIX[:height] + [max_height].pack('N').bth + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
|
|
207
|
-
utxos_between(from, to)
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
def list_unspent_by_addresses(current_block_height, min: 0, max: 9999999, addresses: [])
|
|
211
|
-
script_pubkeys = addresses.map { |a| Bitcoin::Script.parse_from_addr(a).to_hex }
|
|
212
|
-
list_unspent_by_script_pubkeys(current_block_height, min: min, max: max, script_pubkeys: script_pubkeys)
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
def list_unspent_by_script_pubkeys(current_block_height, min: 0, max: 9999999, script_pubkeys: [])
|
|
216
|
-
max_height = current_block_height - min
|
|
217
|
-
min_height = current_block_height - max
|
|
218
|
-
script_pubkeys.map do |key|
|
|
219
|
-
from = KEY_PREFIX[:script] + key + '000000000000000000000000000000000000000000000000000000000000000000000000'
|
|
220
|
-
to = KEY_PREFIX[:script] + key + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
|
|
221
|
-
utxos_between(from, to).with_height(min_height, max_height)
|
|
222
|
-
end.flatten
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
end
|
|
226
|
-
end
|
data/lib/bitcoin/store.rb
DELETED