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.
@@ -36,7 +36,7 @@ module Tapyrus
36
36
 
37
37
  # whether genesis block
38
38
  def genesis?
39
- Tapyrus.chain_params.genesis_block.header == header
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.read(80)), height)
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', # 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
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
- def initialize(db = Tapyrus::Store::DB::LevelDB.new)
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
- def initialize_block
108
+ # @param [Tapyrus::Block] genesis genesis block
109
+ def initialize_block(genesis)
90
110
  unless latest_block
91
- block = Tapyrus.chain_params.genesis_block
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
 
@@ -1,3 +1,3 @@
1
1
  module Tapyrus
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.6"
3
3
  end
@@ -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{[WIP]The implementation of Tapyrus Protocol for Ruby.}
14
- spec.description = %q{[WIP]The implementation of Tapyrus Protocol for Ruby.}
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.1
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-07-15 00:00:00.000000000 Z
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: "[WIP]The implementation of Tapyrus Protocol for Ruby."
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.0.3
424
+ rubygems_version: 3.1.2
451
425
  signing_key:
452
426
  specification_version: 4
453
- summary: "[WIP]The implementation of Tapyrus Protocol for Ruby."
427
+ summary: The implementation of Tapyrus Protocol for Ruby.
454
428
  test_files: []