universa 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/umi/bin/umi +1 -1
- data/bin/umi/bin/umi.bat +1 -1
- data/bin/umi/lib/{com.icodici.common_tools-3.8.4.jar → com.icodici.common_tools-3.8.7.jar} +0 -0
- data/bin/umi/lib/{com.icodici.crypto-3.8.4.jar → com.icodici.crypto-3.8.7.jar} +0 -0
- data/bin/umi/lib/{com.icodici.umi-0.8.11.jar → com.icodici.umi-0.8.12.jar} +0 -0
- data/bin/umi/lib/{com.icodici.universa_core-3.8.4.jar → com.icodici.universa_core-3.8.7.jar} +0 -0
- data/lib/universa/client.rb +118 -70
- data/lib/universa/contract.rb +79 -4
- data/lib/universa/keys.rb +13 -0
- data/lib/universa/service.rb +2 -1
- data/lib/universa/tools.rb +116 -0
- data/lib/universa/umi.rb +1 -1
- data/lib/universa/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df63b3d6f368d3ab12f992d77922e263409e59ccf5941c09737d6231c0098ae7
|
4
|
+
data.tar.gz: 50d82075f8b1e74e8ab1ddad1da9b86fac291e6b7cae6bf90f6c80cdd7b775a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e95c8ace31825fedb9608238ded0eb853406a8e39bb1132897e3e3e38e15f92eb0d18661571df8f9052d12d0ce45f1e67687dd74b013a8c0bd2714f2fa17a37
|
7
|
+
data.tar.gz: 9a873908627df30fd7803fcdf5bbbf70fdbe7d9a814dd2591f501f6d3c39033a17524200928c6e85cf4045f23bbb7426cd6559543621a0832b9cc8739ac9a59e
|
data/bin/umi/bin/umi
CHANGED
@@ -344,7 +344,7 @@ declare -r lib_dir="$(realpath "${app_home}/../lib")"
|
|
344
344
|
declare -a app_mainclass=(com.icodici.farcallscala.Main)
|
345
345
|
|
346
346
|
declare -r script_conf_file="${app_home}/../conf/application.ini"
|
347
|
-
declare -r app_classpath="$lib_dir/com.icodici.umi-0.8.
|
347
|
+
declare -r app_classpath="$lib_dir/com.icodici.umi-0.8.12.jar:$lib_dir/org.scala-lang.scala-library-2.12.7.jar:$lib_dir/com.icodici.universa_core-3.8.7.jar:$lib_dir/org.yaml.snakeyaml-1.18.jar:$lib_dir/net.sf.jopt-simple.jopt-simple-4.9.jar:$lib_dir/org.postgresql.postgresql-42.1.4.jar:$lib_dir/org.xerial.sqlite-jdbc-3.8.9.1.jar:$lib_dir/com.icodici.nanohttpd-2.1.0.jar:$lib_dir/com.icodici.common_tools-3.8.7.jar:$lib_dir/com.eclipsesource.minimal-json.minimal-json-0.9.4.jar:$lib_dir/net.java.dev.jna.jna-4.5.1.jar:$lib_dir/org.checkerframework.checker-qual-2.3.2.jar:$lib_dir/com.icodici.crypto-3.8.7.jar:$lib_dir/com.madgag.spongycastle.core-1.58.0.0.jar:$lib_dir/com.squareup.jnagmp.jnagmp-2.0.0.jar:$lib_dir/com.typesafe.play.play-json_2.12-2.6.10.jar:$lib_dir/com.typesafe.play.play-functional_2.12-2.6.10.jar:$lib_dir/org.scala-lang.scala-reflect-2.12.7.jar:$lib_dir/org.typelevel.macro-compat_2.12-1.1.1.jar:$lib_dir/joda-time.joda-time-2.9.9.jar:$lib_dir/com.fasterxml.jackson.core.jackson-core-2.8.11.jar:$lib_dir/com.fasterxml.jackson.core.jackson-annotations-2.8.11.jar:$lib_dir/com.fasterxml.jackson.datatype.jackson-datatype-jdk8-2.8.11.jar:$lib_dir/com.fasterxml.jackson.core.jackson-databind-2.8.11.1.jar:$lib_dir/com.fasterxml.jackson.datatype.jackson-datatype-jsr310-2.8.11.jar:$lib_dir/org.scala-sbt.ipcsocket.ipcsocket-1.0.0.jar:$lib_dir/net.java.dev.jna.jna-platform-4.5.0.jar"
|
348
348
|
|
349
349
|
# java_cmd is overrode in process_args when -java-home is used
|
350
350
|
declare java_cmd=$(get_java_cmd)
|
data/bin/umi/bin/umi.bat
CHANGED
@@ -80,7 +80,7 @@ rem "-J" is stripped, "-D" is left as is, and everything is appended to JAVA_OPT
|
|
80
80
|
set _JAVA_PARAMS=
|
81
81
|
set _APP_ARGS=
|
82
82
|
|
83
|
-
set "APP_CLASSPATH=%APP_LIB_DIR%\com.icodici.umi-0.8.
|
83
|
+
set "APP_CLASSPATH=%APP_LIB_DIR%\com.icodici.umi-0.8.12.jar;%APP_LIB_DIR%\org.scala-lang.scala-library-2.12.7.jar;%APP_LIB_DIR%\com.icodici.universa_core-3.8.7.jar;%APP_LIB_DIR%\org.yaml.snakeyaml-1.18.jar;%APP_LIB_DIR%\net.sf.jopt-simple.jopt-simple-4.9.jar;%APP_LIB_DIR%\org.postgresql.postgresql-42.1.4.jar;%APP_LIB_DIR%\org.xerial.sqlite-jdbc-3.8.9.1.jar;%APP_LIB_DIR%\com.icodici.nanohttpd-2.1.0.jar;%APP_LIB_DIR%\com.icodici.common_tools-3.8.7.jar;%APP_LIB_DIR%\com.eclipsesource.minimal-json.minimal-json-0.9.4.jar;%APP_LIB_DIR%\net.java.dev.jna.jna-4.5.1.jar;%APP_LIB_DIR%\org.checkerframework.checker-qual-2.3.2.jar;%APP_LIB_DIR%\com.icodici.crypto-3.8.7.jar;%APP_LIB_DIR%\com.madgag.spongycastle.core-1.58.0.0.jar;%APP_LIB_DIR%\com.squareup.jnagmp.jnagmp-2.0.0.jar;%APP_LIB_DIR%\com.typesafe.play.play-json_2.12-2.6.10.jar;%APP_LIB_DIR%\com.typesafe.play.play-functional_2.12-2.6.10.jar;%APP_LIB_DIR%\org.scala-lang.scala-reflect-2.12.7.jar;%APP_LIB_DIR%\org.typelevel.macro-compat_2.12-1.1.1.jar;%APP_LIB_DIR%\joda-time.joda-time-2.9.9.jar;%APP_LIB_DIR%\com.fasterxml.jackson.core.jackson-core-2.8.11.jar;%APP_LIB_DIR%\com.fasterxml.jackson.core.jackson-annotations-2.8.11.jar;%APP_LIB_DIR%\com.fasterxml.jackson.datatype.jackson-datatype-jdk8-2.8.11.jar;%APP_LIB_DIR%\com.fasterxml.jackson.core.jackson-databind-2.8.11.1.jar;%APP_LIB_DIR%\com.fasterxml.jackson.datatype.jackson-datatype-jsr310-2.8.11.jar;%APP_LIB_DIR%\org.scala-sbt.ipcsocket.ipcsocket-1.0.0.jar;%APP_LIB_DIR%\net.java.dev.jna.jna-platform-4.5.0.jar"
|
84
84
|
set "APP_MAIN_CLASS=com.icodici.farcallscala.Main"
|
85
85
|
set "SCRIPT_CONF_FILE=%APP_HOME%\conf\application.ini"
|
86
86
|
|
Binary file
|
Binary file
|
Binary file
|
data/bin/umi/lib/{com.icodici.universa_core-3.8.4.jar → com.icodici.universa_core-3.8.7.jar}
RENAMED
Binary file
|
data/lib/universa/client.rb
CHANGED
@@ -6,79 +6,10 @@ module Universa
|
|
6
6
|
|
7
7
|
using Universa
|
8
8
|
|
9
|
-
def retry_with_timeout(max_timeout = 15, max_times = 3, &block)
|
10
|
-
attempt = 0
|
11
|
-
Timeout::timeout(max_timeout, &block)
|
12
|
-
rescue
|
13
|
-
attempt += 1
|
14
|
-
puts "timeout: retry (#$!): #{attempt}"
|
15
|
-
retry if attempt < max_times
|
16
|
-
raise
|
17
|
-
end
|
18
|
-
|
19
|
-
|
20
|
-
module Parallel
|
21
|
-
|
22
|
-
class ParallelEnumerable < SimpleDelegator
|
23
|
-
include Concurrent
|
24
|
-
|
25
|
-
@@pool = CachedThreadPool.new
|
26
|
-
|
27
|
-
def each_with_index &block
|
28
|
-
latch = CountDownLatch.new(size)
|
29
|
-
__getobj__.each_with_index {|x, index|
|
30
|
-
@@pool << -> {
|
31
|
-
begin
|
32
|
-
block.call(x, index)
|
33
|
-
rescue
|
34
|
-
$!.print_stack_trace
|
35
|
-
ensure
|
36
|
-
latch.count_down
|
37
|
-
end
|
38
|
-
}
|
39
|
-
}
|
40
|
-
latch.wait
|
41
|
-
end
|
42
|
-
|
43
|
-
def each &block
|
44
|
-
each_with_index {|x, i| block.call(x)}
|
45
|
-
end
|
46
|
-
|
47
|
-
|
48
|
-
def map &block
|
49
|
-
result = size.times.map {nil}
|
50
|
-
each_with_index {|value, i|
|
51
|
-
result[i] = block.call(value)
|
52
|
-
}
|
53
|
-
result.par
|
54
|
-
end
|
55
|
-
|
56
|
-
alias_method :collect, :map
|
57
|
-
end
|
58
|
-
|
59
|
-
refine Enumerable do
|
60
|
-
def par
|
61
|
-
is_a?(ParallelEnumerable) ? self : ParallelEnumerable.new(self)
|
62
|
-
end
|
63
|
-
|
64
|
-
def group_by &block
|
65
|
-
result = {}
|
66
|
-
each {|value|
|
67
|
-
new_key = block.call(value)
|
68
|
-
(result[new_key] ||= []) << value
|
69
|
-
}
|
70
|
-
result
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
using Parallel
|
78
|
-
|
79
9
|
# Universa network client reads current network configuration and provides access to each node independently
|
80
10
|
# and also implement newtor-wide procedures.
|
81
11
|
class Client
|
12
|
+
using Universa::Parallel
|
82
13
|
|
83
14
|
# Create client
|
84
15
|
# @param [PrivateKey] private_key to connect with. Generates new one if omitted.
|
@@ -102,6 +33,33 @@ module Universa
|
|
102
33
|
@nodes.sample
|
103
34
|
end
|
104
35
|
|
36
|
+
def register_single contract
|
37
|
+
random_connection.register_single contract
|
38
|
+
end
|
39
|
+
|
40
|
+
# Perform fats consensus state check. E.g. it scans up to 2/3 of the network until
|
41
|
+
# the positive or negative consensus will be found. So far you can only rely on
|
42
|
+
# result.approved? as it returns some last node result which, though, match the
|
43
|
+
# consensus. Aggregation of parameters is under way.
|
44
|
+
#
|
45
|
+
# @param [Contract | HashId] obj to check
|
46
|
+
# @return [ContractState] of some final node check It does not aggregates (yet)
|
47
|
+
def get_state obj
|
48
|
+
result = Concurrent::IVar.new
|
49
|
+
negative_votes = Concurrent::AtomicFixnum.new(@nodes.size * 20 / 100)
|
50
|
+
positive_votes = Concurrent::AtomicFixnum.new(@nodes.size * 30 / 100)
|
51
|
+
random_connections(@nodes.size * 2 / 3).par.each {|conn|
|
52
|
+
if result.incomplete?
|
53
|
+
if (state = conn.get_state(obj)).approved?
|
54
|
+
result.try_set(state) if positive_votes.decrement < 0
|
55
|
+
else
|
56
|
+
result.try_set(state) if negative_votes.decrement < 0
|
57
|
+
end
|
58
|
+
end
|
59
|
+
}
|
60
|
+
result.value
|
61
|
+
end
|
62
|
+
|
105
63
|
# @return [Array(Connection)] array of count randomly selected connections
|
106
64
|
def random_connections count = 1
|
107
65
|
@nodes.sample(count)
|
@@ -144,32 +102,39 @@ module Universa
|
|
144
102
|
class NodeInfo
|
145
103
|
attr :number, :packed_key, :url
|
146
104
|
|
105
|
+
# constructs from binary packed data
|
147
106
|
def initialize(data)
|
148
107
|
@data, @number, @url, @packed_key = data, data.number, data.url, data.packed_key
|
149
108
|
@rate = Concurrent::AtomicFixnum.new
|
150
109
|
end
|
151
110
|
|
111
|
+
# currently collected approval rate
|
152
112
|
def rate
|
153
113
|
@rate.value
|
154
114
|
end
|
155
115
|
|
116
|
+
# increase approval rate
|
156
117
|
def increment_rate
|
157
118
|
@rate.increment
|
158
119
|
end
|
159
120
|
|
121
|
+
# check information euqlity
|
160
122
|
def == other
|
161
123
|
# number == other.number && packed_key == other.packed_key && url == other.url
|
162
124
|
url == other&.url && packed_key == other&.packed_key && url == other&.url
|
163
125
|
end
|
164
126
|
|
127
|
+
# allows to use as hash key
|
165
128
|
def hash
|
166
129
|
@url.hash + @packed_key.hash
|
167
130
|
end
|
168
131
|
|
132
|
+
# to use as hash key
|
169
133
|
def eql?(other)
|
170
134
|
self == other
|
171
135
|
end
|
172
136
|
|
137
|
+
# ordered by approval rate
|
173
138
|
def < other
|
174
139
|
rate < other.rate
|
175
140
|
end
|
@@ -197,6 +162,36 @@ module Universa
|
|
197
162
|
execute(:sping)
|
198
163
|
end
|
199
164
|
|
165
|
+
# Register a single contract (on private network or if you have white key allowing free operations)
|
166
|
+
# on a single node.
|
167
|
+
#
|
168
|
+
# @param [Contract] contract, muts be sealed ({Contract#seal})
|
169
|
+
# @return [ContractState] of the result. Could contain errors.
|
170
|
+
def register_single contract
|
171
|
+
result = ContractState.new(execute "approve", packedItem: contract.packed)
|
172
|
+
while result.is_pending
|
173
|
+
sleep(0.1)
|
174
|
+
result = get_state contract
|
175
|
+
end
|
176
|
+
result
|
177
|
+
end
|
178
|
+
|
179
|
+
# Get contract or hashId state from this single node
|
180
|
+
# @param [Contract | HashId] x what to check
|
181
|
+
# @return [ContractState]
|
182
|
+
def get_state x
|
183
|
+
id = case x
|
184
|
+
when HashId
|
185
|
+
x
|
186
|
+
when Contract
|
187
|
+
x.hash_id
|
188
|
+
else
|
189
|
+
raise ArgumentError, "bad argument, want Contract or HashId"
|
190
|
+
end
|
191
|
+
ContractState.new(execute "getState", itemId: id)
|
192
|
+
end
|
193
|
+
|
194
|
+
|
200
195
|
# Execute Universa Node client protocol command with optional keyword arguments that will be passed
|
201
196
|
# to the node.
|
202
197
|
#
|
@@ -206,6 +201,14 @@ module Universa
|
|
206
201
|
connection.command name.to_s, *kwargs.to_a.flatten
|
207
202
|
end
|
208
203
|
|
204
|
+
def to_s
|
205
|
+
"Conn<#{@node_info.url}>"
|
206
|
+
end
|
207
|
+
|
208
|
+
def inspect
|
209
|
+
to_s
|
210
|
+
end
|
211
|
+
|
209
212
|
protected
|
210
213
|
|
211
214
|
def connection
|
@@ -220,4 +223,49 @@ module Universa
|
|
220
223
|
|
221
224
|
end
|
222
225
|
|
226
|
+
class ContractState
|
227
|
+
def initialize(universa_contract_state)
|
228
|
+
@source = universa_contract_state
|
229
|
+
end
|
230
|
+
|
231
|
+
def errors
|
232
|
+
@source.errors&.map &:to_s
|
233
|
+
rescue
|
234
|
+
"failed to extract errors: #$!"
|
235
|
+
end
|
236
|
+
|
237
|
+
def state
|
238
|
+
@source.itemResult.state
|
239
|
+
end
|
240
|
+
|
241
|
+
def is_pending
|
242
|
+
state.start_with?('PENDING')
|
243
|
+
end
|
244
|
+
|
245
|
+
def is_approved
|
246
|
+
case state
|
247
|
+
when 'APPROVED', 'LOCKED'
|
248
|
+
true
|
249
|
+
else
|
250
|
+
false
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def approved?
|
255
|
+
is_approved
|
256
|
+
end
|
257
|
+
|
258
|
+
def pending?
|
259
|
+
is_pending
|
260
|
+
end
|
261
|
+
|
262
|
+
def to_s
|
263
|
+
"ContractState:#{state}"
|
264
|
+
end
|
265
|
+
|
266
|
+
def inspect
|
267
|
+
to_s
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
223
271
|
end
|
data/lib/universa/contract.rb
CHANGED
@@ -5,6 +5,15 @@ module Universa
|
|
5
5
|
remote_class "com.icodici.universa.contract.permissions.ChangeOwnerPermission"
|
6
6
|
end
|
7
7
|
|
8
|
+
# Adapter for Universa RevokePermission
|
9
|
+
class RevokePermission < RemoteAdapter
|
10
|
+
remote_class "com.icodici.universa.contract.permissions.RevokePermission"
|
11
|
+
end
|
12
|
+
|
13
|
+
class SplitJoinPermission < RemoteAdapter
|
14
|
+
remote_class "com.icodici.universa.contract.permissions.SplitJoinPermission"
|
15
|
+
end
|
16
|
+
|
8
17
|
# Adapter for Universa Role
|
9
18
|
class Role < RemoteAdapter
|
10
19
|
remote_class "com.icodici.universa.contract.roles.Role"
|
@@ -16,18 +25,61 @@ module Universa
|
|
16
25
|
|
17
26
|
# Set object for a key
|
18
27
|
#
|
19
|
-
# @param [Object] key
|
28
|
+
# @param [Object] key key.to_s will be used (so use Symbols or Strings freely)
|
20
29
|
# @param [Object] value
|
21
|
-
def []=(key,value)
|
30
|
+
def []=(key, value)
|
22
31
|
set(key.to_s, value)
|
23
32
|
end
|
24
33
|
|
25
34
|
# Get object by key.
|
26
|
-
# @param [Object] key
|
35
|
+
# @param [Object] key key.to_s will be used (so use Symbols or Strings freely)
|
27
36
|
# @return [Object] or nil
|
28
37
|
def [](key)
|
29
38
|
get(key.to_s)
|
30
39
|
end
|
40
|
+
|
41
|
+
def self.of hash
|
42
|
+
invoke_static "of", hash.transform_keys(&:to_s)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Adapter for Universa +HashId+ class, helps to avoid confusion when using different
|
47
|
+
# representations of the ID.
|
48
|
+
class HashId < RemoteAdapter
|
49
|
+
remote_class "com.icodici.universa.HashId"
|
50
|
+
|
51
|
+
# Construct from binary representation, not to confuse with binary one.
|
52
|
+
#
|
53
|
+
# @param [String] digest_bytes binary string of some +hash_id.bytes+
|
54
|
+
# @return [HashId] instance with instance.bytes == digest.bytes
|
55
|
+
def self.from_digest(digest_bytes)
|
56
|
+
digest_bytes.force_encoding 'binary'
|
57
|
+
invoke_static 'with_digest', digest_bytes
|
58
|
+
end
|
59
|
+
|
60
|
+
# Construct from string representation of the ID, not to confuse with binary one.
|
61
|
+
#
|
62
|
+
# @param [String] string_id id string representation, like from +hash_id_instance.to_s+. See {#to_s}.
|
63
|
+
def self.from_string(string_id)
|
64
|
+
string_id.force_encoding 'utf-8'
|
65
|
+
invoke_static 'with_digest', string_id
|
66
|
+
end
|
67
|
+
|
68
|
+
# Get binary representation. It is shorter than string representation but contain non-printable characters and
|
69
|
+
# can cause problems if treated like a string. Use {#to_s} to get string representation instead.
|
70
|
+
#
|
71
|
+
# @return [String] binary string
|
72
|
+
def bytes
|
73
|
+
get_digest
|
74
|
+
end
|
75
|
+
|
76
|
+
# Get string representation. It is, actually, base64 encoded string representation. Longer, but could easily
|
77
|
+
# be transferred with text protocols.
|
78
|
+
#
|
79
|
+
# @return [String] string representation
|
80
|
+
def to_s
|
81
|
+
Base64.encode64(get_digest).gsub(/\s/, '')
|
82
|
+
end
|
31
83
|
end
|
32
84
|
|
33
85
|
# Universa contract adapter.
|
@@ -56,12 +108,14 @@ module Universa
|
|
56
108
|
contract.register_role(contract.issuer.link_as("owner"))
|
57
109
|
contract.register_role(contract.issuer.link_as("creator"))
|
58
110
|
contract.add_permission ChangeOwnerPermission.new(contract.owner.link_as "@owner")
|
111
|
+
contract.add_permission RevokePermission.new(contract.owner.link_as "@owner")
|
59
112
|
contract.add_signer_key issuer_key
|
60
113
|
contract
|
61
114
|
end
|
62
115
|
|
63
116
|
# Load from transaction pack
|
64
117
|
def self.from_packed packed
|
118
|
+
packed.force_encoding 'binary'
|
65
119
|
self.invoke_static "fromPackedTransaction", packed
|
66
120
|
end
|
67
121
|
|
@@ -108,11 +162,27 @@ module Universa
|
|
108
162
|
get_expires_at
|
109
163
|
end
|
110
164
|
|
165
|
+
def expires_at= time
|
166
|
+
set_expires_at time
|
167
|
+
end
|
168
|
+
|
111
169
|
# @return definition data
|
112
170
|
def definition
|
113
|
-
get_definition.get_data
|
171
|
+
@definition ||= get_definition.get_data
|
172
|
+
end
|
173
|
+
|
174
|
+
def state
|
175
|
+
@state ||= get_state_data
|
114
176
|
end
|
115
177
|
|
178
|
+
def amount
|
179
|
+
v = state[:amount] and BigDecimal(v.to_s)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Get packed transaction containing the serialized signed contract and all its counterparts.
|
183
|
+
# Be sure to cal {#seal} somewhere before.
|
184
|
+
#
|
185
|
+
# @return binary string with packed transaction.
|
116
186
|
def packed
|
117
187
|
get_packed_transaction
|
118
188
|
end
|
@@ -125,6 +195,11 @@ module Universa
|
|
125
195
|
}
|
126
196
|
end
|
127
197
|
|
198
|
+
# def create_revocation *keys
|
199
|
+
# Service.umi.invoke_static 'ContractService', 'createRevocation', *keyss
|
200
|
+
# sel
|
201
|
+
# end
|
202
|
+
|
128
203
|
end
|
129
204
|
|
130
205
|
end
|
data/lib/universa/keys.rb
CHANGED
@@ -5,6 +5,19 @@ module Universa
|
|
5
5
|
class PrivateKey < RemoteAdapter
|
6
6
|
remote_class 'com.icodici.crypto.PrivateKey'
|
7
7
|
|
8
|
+
# Load key from packed, optinally, using the password
|
9
|
+
#
|
10
|
+
# @param [String] packed binary string with packed key
|
11
|
+
# @param [String] password optional password
|
12
|
+
def self.from_packed(packed, password: nil)
|
13
|
+
packed.force_encoding 'binary'
|
14
|
+
if password
|
15
|
+
invoke_static "unpackWithPassword", packed, password
|
16
|
+
else
|
17
|
+
PrivateKey.new packed
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
8
21
|
# @return [KeyAddress] short address of the corresponding public key
|
9
22
|
def short_address
|
10
23
|
@short_address ||= public_key.short_address
|
data/lib/universa/service.rb
CHANGED
@@ -14,7 +14,8 @@ module Universa
|
|
14
14
|
def initialize
|
15
15
|
@config = SmartHash.new path: nil
|
16
16
|
@known_proxies = {}
|
17
|
-
[Contract, PrivateKey, PublicKey, KeyAddress, Binder, Role, ChangeOwnerPermission
|
17
|
+
[Contract, PrivateKey, PublicKey, KeyAddress, HashId, Binder, Role, ChangeOwnerPermission, RevokePermission,
|
18
|
+
SplitJoinPermission].each {|klass| register_proxy klass}
|
18
19
|
end
|
19
20
|
|
20
21
|
# Implementation of {Service.configure}
|
data/lib/universa/tools.rb
CHANGED
@@ -1,8 +1,124 @@
|
|
1
1
|
require 'farcall/smart_hash'
|
2
|
+
require 'concurrent'
|
2
3
|
|
3
4
|
module Universa
|
4
5
|
|
5
6
|
# The Hashie::Mash without warnings, just copied from Farcall to not to copy it again
|
6
7
|
class SmartHash < Farcall::SmartHash
|
7
8
|
end
|
9
|
+
|
10
|
+
def retry_with_timeout(max_timeout = 15, max_times = 3, &block)
|
11
|
+
attempt = 0
|
12
|
+
Timeout::timeout(max_timeout, &block)
|
13
|
+
rescue
|
14
|
+
attempt += 1
|
15
|
+
puts "timeout: retry (#$!): #{attempt}"
|
16
|
+
retry if attempt < max_times
|
17
|
+
raise
|
18
|
+
end
|
19
|
+
|
20
|
+
module Parallel
|
21
|
+
|
22
|
+
# The eollection-like delegate supporting parallel execution on {#each}, {#each_with_index} and {#map}.
|
23
|
+
# Use +refine Enumerable+ to easily construct it as simple as +collection.par+. Inspired by Scala.
|
24
|
+
class ParallelEnumerable < SimpleDelegator
|
25
|
+
include Concurrent
|
26
|
+
|
27
|
+
@@pool = CachedThreadPool.new
|
28
|
+
|
29
|
+
# Enumerates in parallel all items. Like {Enumerable#each_with_index}, but requires block.
|
30
|
+
# Blocks until all items are processed.
|
31
|
+
#
|
32
|
+
# @param [Proc] block to call with (object, index) parameters
|
33
|
+
# @return self
|
34
|
+
def each_with_index &block
|
35
|
+
latch = CountDownLatch.new(size)
|
36
|
+
__getobj__.each_with_index {|x, index|
|
37
|
+
@@pool << -> {
|
38
|
+
begin
|
39
|
+
block.call(x, index)
|
40
|
+
rescue
|
41
|
+
$!.print_stack_trace
|
42
|
+
ensure
|
43
|
+
latch.count_down
|
44
|
+
end
|
45
|
+
}
|
46
|
+
}
|
47
|
+
latch.wait
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
# Call the given block on each item in the collection in parallel, blocks until all items are processed
|
52
|
+
#
|
53
|
+
# @return self
|
54
|
+
def each &block
|
55
|
+
each_with_index {|x, i| block.call(x)}
|
56
|
+
end
|
57
|
+
|
58
|
+
# Parallel version of the {Enumerable#map}. Creates a new array containing the values returned by the block,
|
59
|
+
# using parallel execution in threads.
|
60
|
+
#
|
61
|
+
# @return new array containing the values returned by the block.
|
62
|
+
def map &block
|
63
|
+
result = size.times.map {nil}
|
64
|
+
each_with_index {|value, i|
|
65
|
+
result[i] = block.call(value)
|
66
|
+
}
|
67
|
+
result.par
|
68
|
+
end
|
69
|
+
|
70
|
+
alias_method :collect, :map
|
71
|
+
end
|
72
|
+
|
73
|
+
# Enhance any Enumerable instance with few utilities.
|
74
|
+
refine Enumerable do
|
75
|
+
|
76
|
+
# Creates {ParallelEnumerable} from self.
|
77
|
+
#
|
78
|
+
# @return [ParallelEnumerable] over the self
|
79
|
+
def par
|
80
|
+
is_a?(ParallelEnumerable) ? self : ParallelEnumerable.new(self)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Group elements by the value returned by the block. Return map where keys are one returned by the block
|
84
|
+
# and values are arrays of elements of the given Enumerable with corresponding block.
|
85
|
+
#
|
86
|
+
# @param [Object] block that calculates keys to group with for each source elements.
|
87
|
+
# @return [Hash] of grouped source elements
|
88
|
+
def group_by(&block)
|
89
|
+
result = {}
|
90
|
+
each {|value|
|
91
|
+
new_key = block.call(value)
|
92
|
+
(result[new_key] ||= []) << value
|
93
|
+
}
|
94
|
+
result
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
refine Array do
|
99
|
+
|
100
|
+
# Creates {ParallelEnumerable} from self.
|
101
|
+
#
|
102
|
+
# @return [ParallelEnumerable] over the self
|
103
|
+
def par
|
104
|
+
is_a?(ParallelEnumerable) ? self : ParallelEnumerable.new(self)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Group elements by the value returned by the block. Return map where keys are one returned by the block
|
108
|
+
# and values are arrays of elements of the given Enumerable with corresponding block.
|
109
|
+
#
|
110
|
+
# @param [Object] block that calculates keys to group with for each source elements.
|
111
|
+
# @return [Hash] of grouped source elements
|
112
|
+
def group_by(&block)
|
113
|
+
result = {}
|
114
|
+
each {|value|
|
115
|
+
new_key = block.call(value)
|
116
|
+
(result[new_key] ||= []) << value
|
117
|
+
}
|
118
|
+
result
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
8
124
|
end
|
data/lib/universa/umi.rb
CHANGED
@@ -112,7 +112,7 @@ module Universa
|
|
112
112
|
end
|
113
113
|
|
114
114
|
def invoke_static(class_name, method, *args)
|
115
|
-
encode_result call("invoke", class_name, method, *prepare_args(args))
|
115
|
+
encode_result call("invoke", class_name, method.to_s.camelize_lower, *prepare_args(args))
|
116
116
|
end
|
117
117
|
|
118
118
|
# Close child process. No remote calls should occur after it.
|
data/lib/universa/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: universa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sergeych
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-11-
|
11
|
+
date: 2018-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: farcall
|
@@ -134,11 +134,11 @@ files:
|
|
134
134
|
- bin/umi/lib/com.fasterxml.jackson.core.jackson-databind-2.8.11.1.jar
|
135
135
|
- bin/umi/lib/com.fasterxml.jackson.datatype.jackson-datatype-jdk8-2.8.11.jar
|
136
136
|
- bin/umi/lib/com.fasterxml.jackson.datatype.jackson-datatype-jsr310-2.8.11.jar
|
137
|
-
- bin/umi/lib/com.icodici.common_tools-3.8.
|
138
|
-
- bin/umi/lib/com.icodici.crypto-3.8.
|
137
|
+
- bin/umi/lib/com.icodici.common_tools-3.8.7.jar
|
138
|
+
- bin/umi/lib/com.icodici.crypto-3.8.7.jar
|
139
139
|
- bin/umi/lib/com.icodici.nanohttpd-2.1.0.jar
|
140
|
-
- bin/umi/lib/com.icodici.umi-0.8.
|
141
|
-
- bin/umi/lib/com.icodici.universa_core-3.8.
|
140
|
+
- bin/umi/lib/com.icodici.umi-0.8.12.jar
|
141
|
+
- bin/umi/lib/com.icodici.universa_core-3.8.7.jar
|
142
142
|
- bin/umi/lib/com.madgag.spongycastle.core-1.58.0.0.jar
|
143
143
|
- bin/umi/lib/com.squareup.jnagmp.jnagmp-2.0.0.jar
|
144
144
|
- bin/umi/lib/com.typesafe.play.play-functional_2.12-2.6.10.jar
|