tapyrus 0.2.1 → 0.2.6
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/.travis.yml +5 -3
- data/README.md +1 -1
- data/lib/schnorr.rb +1 -1
- data/lib/tapyrus.rb +2 -7
- data/lib/tapyrus/block.rb +3 -7
- data/lib/tapyrus/block_header.rb +66 -38
- data/lib/tapyrus/chain_params.rb +0 -10
- data/lib/tapyrus/chainparams/dev.yml +0 -10
- data/lib/tapyrus/chainparams/prod.yml +0 -9
- data/lib/tapyrus/errors.rb +17 -0
- data/lib/tapyrus/ext/ecdsa.rb +39 -0
- data/lib/tapyrus/ext_key.rb +39 -15
- data/lib/tapyrus/key.rb +15 -36
- data/lib/tapyrus/message/block.rb +1 -1
- data/lib/tapyrus/message/header_and_short_ids.rb +1 -1
- data/lib/tapyrus/message/headers.rb +1 -1
- data/lib/tapyrus/message/merkle_block.rb +1 -1
- data/lib/tapyrus/rpc/request_handler.rb +5 -4
- data/lib/tapyrus/rpc/tapyrus_core_client.rb +1 -1
- data/lib/tapyrus/script/color.rb +10 -2
- data/lib/tapyrus/script/script.rb +30 -0
- data/lib/tapyrus/script/tx_checker.rb +7 -3
- data/lib/tapyrus/secp256k1/native.rb +93 -20
- data/lib/tapyrus/secp256k1/ruby.rb +62 -27
- data/lib/tapyrus/store/chain_entry.rb +2 -2
- data/lib/tapyrus/store/db/level_db.rb +58 -0
- data/lib/tapyrus/store/spv_chain.rb +29 -11
- data/lib/tapyrus/version.rb +1 -1
- data/tapyrusrb.gemspec +2 -4
- metadata +7 -33
@@ -36,7 +36,7 @@ module Tapyrus
|
|
36
36
|
|
37
37
|
# whether genesis block
|
38
38
|
def genesis?
|
39
|
-
|
39
|
+
height == 0
|
40
40
|
end
|
41
41
|
|
42
42
|
# @param [String] payload a payload with binary format.
|
@@ -44,7 +44,7 @@ module Tapyrus
|
|
44
44
|
buf = StringIO.new(payload)
|
45
45
|
len = Tapyrus.unpack_var_int_from_io(buf)
|
46
46
|
height = buf.read(len).reverse.bth.to_i(16)
|
47
|
-
new(Tapyrus::BlockHeader.parse_from_payload(buf
|
47
|
+
new(Tapyrus::BlockHeader.parse_from_payload(buf), height)
|
48
48
|
end
|
49
49
|
|
50
50
|
# build next block +StoredBlock+ instance.
|
@@ -58,14 +58,64 @@ module Tapyrus
|
|
58
58
|
db.get(KEY_PREFIX[:entry] + hash)
|
59
59
|
end
|
60
60
|
|
61
|
+
# Save entry.
|
62
|
+
# @param [Tapyrus::Store::ChainEntry]
|
61
63
|
def save_entry(entry)
|
62
64
|
db.batch do
|
63
65
|
db.put(entry.key ,entry.to_payload)
|
64
66
|
db.put(height_key(entry.height), entry.block_hash)
|
67
|
+
add_agg_pubkey(entry.height == 0 ? 0 : entry.height + 1, entry.header.x_field) if entry.header.upgrade_agg_pubkey?
|
65
68
|
connect_entry(entry)
|
66
69
|
end
|
67
70
|
end
|
68
71
|
|
72
|
+
# Add aggregated public key.
|
73
|
+
# @param [Integer] activate_height
|
74
|
+
# @param [String] agg_pubkey aggregated public key with hex format.
|
75
|
+
def add_agg_pubkey(activate_height, agg_pubkey)
|
76
|
+
payload = activate_height.to_even_length_hex + agg_pubkey
|
77
|
+
index = latest_agg_pubkey_index
|
78
|
+
next_index = (index.nil? ? 0 : index + 1).to_even_length_hex
|
79
|
+
db.batch do
|
80
|
+
db.put(KEY_PREFIX[:agg_pubkey] + next_index, payload)
|
81
|
+
db.put(KEY_PREFIX[:latest_agg_pubkey], next_index)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Get aggregated public key by specifying +index+.
|
86
|
+
# @param [Integer] index
|
87
|
+
# @return [Array] tupple of activate height and aggregated public key.
|
88
|
+
def agg_pubkey(index)
|
89
|
+
payload = db.get(KEY_PREFIX[:agg_pubkey] + index.to_even_length_hex)
|
90
|
+
[payload[0...(payload.length - 66)].to_i(16), payload[(payload.length - 66)..-1]]
|
91
|
+
end
|
92
|
+
|
93
|
+
# Get aggregated public key by specifying block +height+.
|
94
|
+
# @param [Integer] height block height.
|
95
|
+
# @return [String] aggregated public key with hex format.
|
96
|
+
def agg_pubkey_with_height(height)
|
97
|
+
index = latest_agg_pubkey_index
|
98
|
+
index ||= 0
|
99
|
+
(index + 1).times do |i|
|
100
|
+
target = index - i
|
101
|
+
active_height, pubkey = agg_pubkey(target)
|
102
|
+
return pubkey unless active_height > height
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Get latest aggregated public key.
|
107
|
+
# @return [Array] aggregated public key with hex format.
|
108
|
+
def latest_agg_pubkey
|
109
|
+
agg_pubkey(latest_agg_pubkey_index)[1]
|
110
|
+
end
|
111
|
+
|
112
|
+
# Get aggregated public key list.
|
113
|
+
# @return [Array[Array]] list of public key and index
|
114
|
+
def agg_pubkeys
|
115
|
+
index = latest_agg_pubkey_index
|
116
|
+
(index + 1).times.map { |i| agg_pubkey(i) }
|
117
|
+
end
|
118
|
+
|
69
119
|
def close
|
70
120
|
db.close
|
71
121
|
end
|
@@ -91,6 +141,14 @@ module Tapyrus
|
|
91
141
|
db.put(KEY_PREFIX[:best], entry.block_hash)
|
92
142
|
db.put(KEY_PREFIX[:next] + entry.prev_hash, entry.block_hash)
|
93
143
|
end
|
144
|
+
|
145
|
+
# Get latest aggregated public key index.
|
146
|
+
# @return [Integer] key index
|
147
|
+
def latest_agg_pubkey_index
|
148
|
+
index = db.get(KEY_PREFIX[:latest_agg_pubkey])
|
149
|
+
index&.to_i(16)
|
150
|
+
end
|
151
|
+
|
94
152
|
end
|
95
153
|
|
96
154
|
end
|
@@ -3,10 +3,12 @@ module Tapyrus
|
|
3
3
|
module Store
|
4
4
|
|
5
5
|
KEY_PREFIX = {
|
6
|
-
entry: 'e',
|
7
|
-
height: 'h',
|
8
|
-
best: 'B',
|
9
|
-
next: 'n'
|
6
|
+
entry: 'e', # key: block hash, value: Tapyrus::Store::ChainEntry payload
|
7
|
+
height: 'h', # key: block height, value: block hash.
|
8
|
+
best: 'B', # value: best block hash.
|
9
|
+
next: 'n', # key: block hash, value: A hash of the next block of the specified hash
|
10
|
+
agg_pubkey: 'a', # key: index, value: Activated block height | aggregated public key.
|
11
|
+
latest_agg_pubkey: 'g' # value: latest agg pubkey index.
|
10
12
|
}
|
11
13
|
|
12
14
|
class SPVChain
|
@@ -14,10 +16,14 @@ module Tapyrus
|
|
14
16
|
attr_reader :db
|
15
17
|
attr_reader :logger
|
16
18
|
|
17
|
-
|
19
|
+
# initialize spv chain
|
20
|
+
# @param[Tapyrus::Store::DB::LevelDB] db
|
21
|
+
# @param[Tapyrus::Block] genesis genesis block
|
22
|
+
def initialize(db = Tapyrus::Store::DB::LevelDB.new, genesis: nil)
|
23
|
+
raise ArgumentError, 'genesis block should be specified.' unless genesis
|
18
24
|
@db = db # TODO multiple db switch
|
19
25
|
@logger = Tapyrus::Logger.create(:debug)
|
20
|
-
initialize_block
|
26
|
+
initialize_block(genesis)
|
21
27
|
end
|
22
28
|
|
23
29
|
# get latest block in the store.
|
@@ -45,9 +51,9 @@ module Tapyrus
|
|
45
51
|
# @return [Tapyrus::Store::ChainEntry] appended block header entry.
|
46
52
|
def append_header(header)
|
47
53
|
logger.info("append header #{header.block_id}")
|
48
|
-
raise "this header is invalid. #{header.block_hash}" unless header.valid?
|
49
54
|
best_block = latest_block
|
50
55
|
current_height = best_block.height
|
56
|
+
raise "this header is invalid. #{header.block_hash}" unless header.valid?(db.agg_pubkey_with_height(current_height + 1))
|
51
57
|
if best_block.block_hash == header.prev_hash
|
52
58
|
entry = Tapyrus::Store::ChainEntry.new(header, current_height + 1)
|
53
59
|
db.save_entry(entry)
|
@@ -83,14 +89,26 @@ module Tapyrus
|
|
83
89
|
time[time.size / 2]
|
84
90
|
end
|
85
91
|
|
92
|
+
# Add aggregated public key.
|
93
|
+
# @param [Integer] active_height
|
94
|
+
# @param [String] agg_pubkey aggregated public key with hex format.
|
95
|
+
def add_agg_pubkey(active_height, agg_pubkey)
|
96
|
+
db.add_agg_pubkey(active_height, agg_pubkey)
|
97
|
+
end
|
98
|
+
|
99
|
+
# get aggregated public key keys.
|
100
|
+
# @return [Array[Array(height, agg_pubkey)]] the list of public keys.
|
101
|
+
def agg_pubkeys
|
102
|
+
db.agg_pubkeys
|
103
|
+
end
|
104
|
+
|
86
105
|
private
|
87
106
|
|
88
107
|
# if database is empty, put genesis block.
|
89
|
-
|
108
|
+
# @param [Tapyrus::Block] genesis genesis block
|
109
|
+
def initialize_block(genesis)
|
90
110
|
unless latest_block
|
91
|
-
|
92
|
-
genesis = ChainEntry.new(block.header, 0)
|
93
|
-
db.save_entry(genesis)
|
111
|
+
db.save_entry(ChainEntry.new(genesis.header, 0))
|
94
112
|
end
|
95
113
|
end
|
96
114
|
|
data/lib/tapyrus/version.rb
CHANGED
data/tapyrusrb.gemspec
CHANGED
@@ -10,8 +10,8 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.authors = ["azuchi"]
|
11
11
|
spec.email = ["azuchi@chaintope.com"]
|
12
12
|
|
13
|
-
spec.summary = %q{
|
14
|
-
spec.description = %q{
|
13
|
+
spec.summary = %q{The implementation of Tapyrus Protocol for Ruby.}
|
14
|
+
spec.description = %q{The implementation of Tapyrus Protocol for Ruby.}
|
15
15
|
spec.homepage = 'https://github.com/chaintope/tapyrusrb'
|
16
16
|
spec.license = "MIT"
|
17
17
|
|
@@ -30,8 +30,6 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_runtime_dependency 'eventmachine_httpserver'
|
31
31
|
spec.add_runtime_dependency 'iniparse'
|
32
32
|
spec.add_runtime_dependency 'siphash'
|
33
|
-
spec.add_runtime_dependency 'protobuf', '3.8.5'
|
34
|
-
spec.add_runtime_dependency 'scrypt'
|
35
33
|
spec.add_runtime_dependency 'activesupport', '>= 5.2.3'
|
36
34
|
spec.add_runtime_dependency 'json_pure', '>= 2.3.1'
|
37
35
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tapyrus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ecdsa
|
@@ -150,34 +150,6 @@ dependencies:
|
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: protobuf
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - '='
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: 3.8.5
|
160
|
-
type: :runtime
|
161
|
-
prerelease: false
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
163
|
-
requirements:
|
164
|
-
- - '='
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
version: 3.8.5
|
167
|
-
- !ruby/object:Gem::Dependency
|
168
|
-
name: scrypt
|
169
|
-
requirement: !ruby/object:Gem::Requirement
|
170
|
-
requirements:
|
171
|
-
- - ">="
|
172
|
-
- !ruby/object:Gem::Version
|
173
|
-
version: '0'
|
174
|
-
type: :runtime
|
175
|
-
prerelease: false
|
176
|
-
version_requirements: !ruby/object:Gem::Requirement
|
177
|
-
requirements:
|
178
|
-
- - ">="
|
179
|
-
- !ruby/object:Gem::Version
|
180
|
-
version: '0'
|
181
153
|
- !ruby/object:Gem::Dependency
|
182
154
|
name: activesupport
|
183
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -290,7 +262,7 @@ dependencies:
|
|
290
262
|
- - "~>"
|
291
263
|
- !ruby/object:Gem::Version
|
292
264
|
version: '3.0'
|
293
|
-
description:
|
265
|
+
description: The implementation of Tapyrus Protocol for Ruby.
|
294
266
|
email:
|
295
267
|
- azuchi@chaintope.com
|
296
268
|
executables:
|
@@ -328,7 +300,9 @@ files:
|
|
328
300
|
- lib/tapyrus/chainparams/dev.yml
|
329
301
|
- lib/tapyrus/chainparams/prod.yml
|
330
302
|
- lib/tapyrus/constants.rb
|
303
|
+
- lib/tapyrus/errors.rb
|
331
304
|
- lib/tapyrus/ext.rb
|
305
|
+
- lib/tapyrus/ext/ecdsa.rb
|
332
306
|
- lib/tapyrus/ext/json_parser.rb
|
333
307
|
- lib/tapyrus/ext_key.rb
|
334
308
|
- lib/tapyrus/key.rb
|
@@ -447,8 +421,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
447
421
|
- !ruby/object:Gem::Version
|
448
422
|
version: '0'
|
449
423
|
requirements: []
|
450
|
-
rubygems_version: 3.
|
424
|
+
rubygems_version: 3.1.2
|
451
425
|
signing_key:
|
452
426
|
specification_version: 4
|
453
|
-
summary:
|
427
|
+
summary: The implementation of Tapyrus Protocol for Ruby.
|
454
428
|
test_files: []
|