universa 0.2.6 → 0.3.1
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/README.md +7 -7
- data/bin/refresh_umi +1 -1
- data/bin/umi/bin/umi +1 -1
- data/bin/umi/bin/umi.bat +1 -1
- data/bin/umi/lib/com.eclipsesource.minimal-json.minimal-json-0.9.4.jar +0 -0
- data/bin/umi/lib/{com.icodici.common_tools-3.8.8.jar → com.icodici.common_tools-3.9.9.jar} +0 -0
- data/bin/umi/lib/{com.icodici.crypto-3.8.8.jar → com.icodici.crypto-3.9.9.jar} +0 -0
- data/bin/umi/lib/{com.icodici.umi-0.8.19.jar → com.icodici.umi-0.8.29.jar} +0 -0
- data/bin/umi/lib/com.icodici.universa_core-3.9.9.jar +0 -0
- data/bin/umi/lib/joda-time.joda-time-2.9.9.jar +0 -0
- data/lib/universa/chain_store.rb +1 -1
- data/lib/universa/client.rb +119 -192
- data/lib/universa/fs_store/file_store.rb +1 -1
- data/lib/universa/service.rb +3 -3
- data/lib/universa/u_settings.rb +6 -0
- data/lib/universa/umi.rb +9 -2
- data/lib/universa/version.rb +1 -1
- metadata +9 -6
- data/bin/umi/lib/com.icodici.universa_core-3.8.8.jar +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7752fa8898467b2d9c15b36fbd2e42714190ba243adcd83ce8998b75ffc2cb91
|
|
4
|
+
data.tar.gz: 45cccb4f84d884276a7d1dcb90d2ea45f7f51b5ec089588254c91dbd2cea6ae9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f6a88953548a26c93e2cc93ee4301185e5536f8aaa4a5801b76912a1e8b8bfb69bff4af6aa74085cbc1fef75969ccb6cb150bacb505ff30b6e62b160d4279e6f
|
|
7
|
+
data.tar.gz: 7b715ea9610753ffd66306a81a3d1dcc4c691b9251fc172c1d10aafe18f1bb741962b90e63cad7523e75a0215e49de5d7c12f67fb9fd3fe826e50e5895eb8dde
|
data/README.md
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
for direct access to remote objects.
|
|
5
5
|
|
|
6
6
|
This is an under-construction official gem from [Universa][universa] to facilitate access to the
|
|
7
|
-
Java library using Universa's UMI protocol.
|
|
7
|
+
Java library using Universa's UMI protocol and Universa client services.
|
|
8
8
|
|
|
9
9
|
## News
|
|
10
10
|
|
|
11
|
+
- rewritten Client and Connection to use new consensus-based, dns-free Universa network topology discovery protocol
|
|
11
12
|
- added syntax sugar for TransactionPack
|
|
12
13
|
- alfa version of the local FS-based contract store.
|
|
13
14
|
- ability to edit `contract.state` and `contract.transactional` in new revisions.
|
|
@@ -63,15 +64,14 @@ puts "Contract id: #{contract.getId.toBase64String}" #=> contract id: x9Ey+q...
|
|
|
63
64
|
contract_id = contract.get_id.to_base64_string
|
|
64
65
|
|
|
65
66
|
```
|
|
66
|
-
|
|
67
67
|
## Docs and resources
|
|
68
68
|
|
|
69
69
|
for more information see:
|
|
70
70
|
|
|
71
|
-
- [Universa gem page](https://kb.
|
|
72
|
-
- Universa Java API: https://kb.
|
|
73
|
-
- Universa UMI server: https://kb.
|
|
74
|
-
- Ruby [docs online](https://kb.
|
|
71
|
+
- [Universa gem page](https://kb.universablockchain.com/universa_ruby_gem/131) in the Universa Knowledge Base.
|
|
72
|
+
- Universa Java API: https://kb.universablockchain.com/general_java_api/5
|
|
73
|
+
- Universa UMI server: https://kb.universablockchain.com/umi_protocol/98
|
|
74
|
+
- Ruby [docs online](https://kb.universablockchain.com/system/static/gem_universa/)
|
|
75
75
|
- Farcall [gem](https://github.com/sergeych/farcall) and [protocol](https://github.com/sergeych/farcall/wiki).
|
|
76
76
|
|
|
77
77
|
### Use UMI service (alfa state)
|
|
@@ -108,4 +108,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
|
108
108
|
|
|
109
109
|
Everyone interacting in the Universa project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/universa/blob/master/CODE_OF_CONDUCT.md).
|
|
110
110
|
|
|
111
|
-
[universa]:
|
|
111
|
+
[universa]:https://universablockchain.com
|
data/bin/refresh_umi
CHANGED
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.29.jar:$lib_dir/org.scala-lang.scala-library-2.12.7.jar:$lib_dir/com.icodici.universa_core-3.9.9.jar:$lib_dir/org.yaml.snakeyaml-1.18.jar:$lib_dir/com.icodici.nanohttpd-2.1.0.jar:$lib_dir/com.icodici.common_tools-3.9.9.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.9.9.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:$lib_dir/net.sf.jopt-simple.jopt-simple-4.9.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.29.jar;%APP_LIB_DIR%\org.scala-lang.scala-library-2.12.7.jar;%APP_LIB_DIR%\com.icodici.universa_core-3.9.9.jar;%APP_LIB_DIR%\org.yaml.snakeyaml-1.18.jar;%APP_LIB_DIR%\com.icodici.nanohttpd-2.1.0.jar;%APP_LIB_DIR%\com.icodici.common_tools-3.9.9.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.9.9.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;%APP_LIB_DIR%\net.sf.jopt-simple.jopt-simple-4.9.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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/universa/chain_store.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Universa
|
|
|
4
4
|
|
|
5
5
|
# The storage interface capable to store contracts in chains, providing search and attributes.
|
|
6
6
|
# This class is not a store itself but the base class for it, having common boilerplate and
|
|
7
|
-
# sort of interface to implement.
|
|
7
|
+
# sort of interface to implement. _Under development, we might change it_
|
|
8
8
|
class ChainStore
|
|
9
9
|
|
|
10
10
|
# Save contract to the store. When this method returns, the contract must me already stored.
|
data/lib/universa/client.rb
CHANGED
|
@@ -4,195 +4,148 @@ require 'concurrent'
|
|
|
4
4
|
|
|
5
5
|
module Universa
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
# The low-level adapter for the UMI Universa client. We provide convenience wrappers for it
|
|
8
|
+
# {Client} and {Connection} classes, more rubyish in interface paradigm, so there is no need to use it directly.
|
|
9
|
+
class UmiClient < RemoteAdapter
|
|
10
|
+
remote_class "com.icodici.universa.node2.network.Client"
|
|
11
|
+
end
|
|
12
|
+
|
|
8
13
|
|
|
9
|
-
#
|
|
10
|
-
# and
|
|
14
|
+
# The universa network client. Discover and connects to the universa network, provides consensus operations
|
|
15
|
+
# and all other whole-network related functions.
|
|
11
16
|
class Client
|
|
12
17
|
using Universa::Parallel
|
|
13
18
|
include Universa
|
|
14
19
|
|
|
15
|
-
|
|
20
|
+
# Discovered network size
|
|
21
|
+
attr :size
|
|
16
22
|
|
|
17
|
-
#
|
|
18
|
-
|
|
19
|
-
def initialize private_key = nil
|
|
20
|
-
@connection_key = private_key
|
|
21
|
-
scan_network()
|
|
22
|
-
end
|
|
23
|
+
# Client private key ised in the connection
|
|
24
|
+
attr :private_key
|
|
23
25
|
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
# Construct an Universa network client. Bu default, connects to the main network. Perform consensus-based
|
|
27
|
+
# network scanning and saves the current network topology in the cache on the file system, default is under
|
|
28
|
+
# +~/.universa+ but could be overriden.
|
|
29
|
+
#
|
|
30
|
+
# If the network topology file is presented but the cached topology is newer, the cached will be used.
|
|
31
|
+
#
|
|
32
|
+
# The client accepts small network topology changes as long as it still create consensus. Still, too big changes
|
|
33
|
+
# in the network topology might require fresh topology file (or upgrade the gem).
|
|
34
|
+
#
|
|
35
|
+
#
|
|
36
|
+
# @param [String] topology: could be name of known network (e.g. mainnet as by default) or path to a .json file
|
|
37
|
+
# containing some network topology, for example, obtained from some external source like telegram
|
|
38
|
+
# channel.
|
|
39
|
+
# @param [PrivateKey] private_key to connect with.
|
|
40
|
+
# @param [String] cache_dir where to store resulting topology. we recommend to leave it as nil.
|
|
41
|
+
#
|
|
42
|
+
# @raise if network topology could not be checked/obtained.
|
|
43
|
+
def initialize topology: "mainnet", private_key: PrivateKey.new(2048), cache_dir: nil
|
|
44
|
+
@client = UmiClient.new topology, cache_dir, private_key
|
|
45
|
+
@private_key = PrivateKey
|
|
46
|
+
@size = @client.size
|
|
47
|
+
@connections = (0...@size).map {nil}
|
|
27
48
|
end
|
|
28
49
|
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
|
|
50
|
+
# Get the node connection by its index (0...size).
|
|
51
|
+
# @return [Connection] object
|
|
52
|
+
def [] index
|
|
53
|
+
raise IndexError if index < 0 || index >= @size
|
|
54
|
+
@connections[index] ||= Connection.new(@client.getClient(index))
|
|
32
55
|
end
|
|
33
56
|
|
|
34
|
-
#
|
|
57
|
+
# Get the random node connection
|
|
58
|
+
# @return [Connection] node connection
|
|
35
59
|
def random_connection
|
|
36
|
-
|
|
60
|
+
self[rand(0...size)]
|
|
37
61
|
end
|
|
38
62
|
|
|
39
|
-
|
|
40
|
-
|
|
63
|
+
# Get several random connections
|
|
64
|
+
# @param [Numeric] number of connections to get
|
|
65
|
+
# @return [Array(Connection)] array of connections to random (non repeating) nodes
|
|
66
|
+
def random_connections number
|
|
67
|
+
(0...size).to_a.sample(number).map {|n| self[n]}
|
|
41
68
|
end
|
|
42
69
|
|
|
43
|
-
# Perform
|
|
44
|
-
# the
|
|
45
|
-
#
|
|
46
|
-
# consensus. Aggregation of parameters is under way.
|
|
70
|
+
# Perform fast consensus state check with a given trust level, as the fraction of the whole network size.
|
|
71
|
+
# It checks the network nodes randomly until get enough positive or negative states. The lover the required
|
|
72
|
+
# trust level is, the faster the answer will be found.
|
|
47
73
|
#
|
|
48
|
-
# @param [Contract | HashId] obj to check
|
|
49
|
-
# @
|
|
50
|
-
|
|
74
|
+
# @param [Contract | HashId] obj contract to check
|
|
75
|
+
# @param [Object] trust level, should be between 0.1 (10% of network) and 0.9 (90% of the network)
|
|
76
|
+
# @return [ContractState] of some final node check It does not calculates average time (yet)
|
|
77
|
+
def get_state obj, trust: 0.3
|
|
78
|
+
raise ArgumentError, "trusst must be in 0.1..0.9 range" if trust < 0.1 || trust > 0.9
|
|
51
79
|
result = Concurrent::IVar.new
|
|
52
|
-
negative_votes = Concurrent::AtomicFixnum.new(
|
|
53
|
-
positive_votes = Concurrent::AtomicFixnum.new(
|
|
54
|
-
|
|
55
|
-
|
|
80
|
+
negative_votes = Concurrent::AtomicFixnum.new((size * 0.1).round + 1)
|
|
81
|
+
positive_votes = Concurrent::AtomicFixnum.new((size * trust).round)
|
|
82
|
+
|
|
83
|
+
# consensus-finding conveyor: we chek connections in batches in parallel until get
|
|
84
|
+
# some consensus. We do not wait until all of them will answer
|
|
85
|
+
(0...size).to_a.shuffle.each {|index|
|
|
86
|
+
Thread.start {
|
|
56
87
|
if result.incomplete?
|
|
57
|
-
if (state =
|
|
88
|
+
if (state = self[index].get_state(obj)).approved?
|
|
58
89
|
result.try_set(state) if positive_votes.decrement < 0
|
|
59
90
|
else
|
|
60
91
|
result.try_set(state) if negative_votes.decrement < 0
|
|
61
92
|
end
|
|
62
93
|
end
|
|
63
94
|
}
|
|
64
|
-
result.value
|
|
65
95
|
}
|
|
96
|
+
result.value
|
|
66
97
|
end
|
|
67
98
|
|
|
68
|
-
#
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def scan_network
|
|
81
|
-
# Todo: cache known nodes
|
|
82
|
-
root_nodes = (1..30).map {|n| "http://node-#{n}-com.utoken.io:8080/network"}
|
|
83
|
-
|
|
84
|
-
# We scan random 70% for consensus
|
|
85
|
-
n = root_nodes.size * 0.7
|
|
86
|
-
|
|
87
|
-
candidates = {}
|
|
88
|
-
root_nodes.sample(n).par.each {|path|
|
|
89
|
-
retry_with_timeout(5, 3) {
|
|
90
|
-
SmartHash.new(Boss.unpack open(path).read).response.nodes.each {|data|
|
|
91
|
-
ni = NodeInfo.new(data)
|
|
92
|
-
(candidates[ni] ||= ni).increment_rate
|
|
93
|
-
}
|
|
94
|
-
}
|
|
99
|
+
# Register a single contract (on private network or if you have white key allowing free operations)
|
|
100
|
+
# on a random node. Client must check returned contract state. It requires "open" network or special
|
|
101
|
+
# key that has a right to register contracts without payment.
|
|
102
|
+
#
|
|
103
|
+
# When retrying, randpm nodes are selected.
|
|
104
|
+
#
|
|
105
|
+
# @param [Contract] contract must be sealed ({Contract#seal})
|
|
106
|
+
#
|
|
107
|
+
# @return [ContractState] of the result. Could contain errors.
|
|
108
|
+
def register_single(contract, timeout: 45, max_retries: 3)
|
|
109
|
+
retry_with_timeout(timeout, max_retries) {
|
|
110
|
+
ContractState.new(random_connection.register_single(contract, timeout / max_retries * 1000 - 100))
|
|
95
111
|
}
|
|
96
|
-
nodes = candidates.values.group_by(&:url)
|
|
97
|
-
.transform_values!(&:sort)
|
|
98
|
-
# We roughly assume the full network size as:
|
|
99
|
-
network_max_size = nodes.size
|
|
100
|
-
# Refine result: takes most voted nodes and only these with 80% consensus
|
|
101
|
-
# and map it to Connection objects
|
|
102
|
-
min_rate = n * 0.8
|
|
103
|
-
@nodes = nodes.values.map {|v| v[-1]}.delete_if {|v| v.rate < min_rate}
|
|
104
|
-
.map {|ni| Connection.new(self, ni)}
|
|
105
|
-
raise NetworkError, "network is not ready" if @nodes.size < network_max_size * 0.9
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# The node information
|
|
110
|
-
class NodeInfo
|
|
111
|
-
attr :number, :packed_key, :url
|
|
112
|
-
|
|
113
|
-
# constructs from binary packed data
|
|
114
|
-
def initialize(data)
|
|
115
|
-
@data, @number, @url, @packed_key = data, data.number, data.url, data.packed_key
|
|
116
|
-
@rate = Concurrent::AtomicFixnum.new
|
|
117
112
|
end
|
|
118
113
|
|
|
119
|
-
|
|
120
|
-
def rate
|
|
121
|
-
@rate.value
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# increase approval rate
|
|
125
|
-
def increment_rate
|
|
126
|
-
@rate.increment
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
# check information euqlity
|
|
130
|
-
def == other
|
|
131
|
-
# number == other.number && packed_key == other.packed_key && url == other.url
|
|
132
|
-
url == other&.url && packed_key == other&.packed_key && url == other&.url
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# allows to use as hash key
|
|
136
|
-
def hash
|
|
137
|
-
@url.hash + @packed_key.hash
|
|
138
|
-
end
|
|
114
|
+
end
|
|
139
115
|
|
|
140
|
-
|
|
141
|
-
def eql?(other)
|
|
142
|
-
self == other
|
|
143
|
-
end
|
|
116
|
+
class Connection
|
|
144
117
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
rate < other.rate
|
|
118
|
+
def initialize umi_client
|
|
119
|
+
@client = umi_client
|
|
148
120
|
end
|
|
149
121
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
122
|
+
# Check the connected node is alive. It is adivesd to call {restart} on nodes that return false on pings
|
|
123
|
+
# to reestablish connection.
|
|
124
|
+
#
|
|
125
|
+
# @return true if it is ok
|
|
126
|
+
def ping
|
|
127
|
+
@client.ping
|
|
155
128
|
end
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
# Access to the single node using universa client protocol.
|
|
160
|
-
#
|
|
161
|
-
class Connection
|
|
162
|
-
include Universa
|
|
163
129
|
|
|
164
|
-
#
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
# needed.
|
|
168
|
-
#
|
|
169
|
-
# @param [Client] client instance to be bound to
|
|
170
|
-
# @param [NodeInfo] node_info to connect to
|
|
171
|
-
def initialize(client, node_info)
|
|
172
|
-
@client, @node_info = client, node_info
|
|
130
|
+
# Attempt to reestablish connection to the node
|
|
131
|
+
def restart
|
|
132
|
+
@client.restart
|
|
173
133
|
end
|
|
174
134
|
|
|
175
|
-
#
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def ping
|
|
179
|
-
execute(:sping)
|
|
135
|
+
# node url (IP-based)
|
|
136
|
+
def url
|
|
137
|
+
@url ||= @client.get_url
|
|
180
138
|
end
|
|
181
139
|
|
|
182
140
|
# Register a single contract (on private network or if you have white key allowing free operations)
|
|
183
|
-
#
|
|
141
|
+
# with the current node. Client must check returned contract state. It requires "open" network or special
|
|
142
|
+
# key that has a right to register contracts without payment.
|
|
184
143
|
#
|
|
185
144
|
# @param [Contract] contract must be sealed ({Contract#seal})
|
|
145
|
+
#
|
|
186
146
|
# @return [ContractState] of the result. Could contain errors.
|
|
187
|
-
def register_single(contract)
|
|
188
|
-
|
|
189
|
-
result = ContractState.new(execute "approve", packedItem: contract.packed)
|
|
190
|
-
while result.is_pending
|
|
191
|
-
sleep(0.1)
|
|
192
|
-
result = get_state contract
|
|
193
|
-
end
|
|
194
|
-
result
|
|
195
|
-
}
|
|
147
|
+
def register_single(contract, timeout = 25)
|
|
148
|
+
ContractState.new(@client.register(contract.packed, timeout * 1000))
|
|
196
149
|
end
|
|
197
150
|
|
|
198
151
|
# Get contract or hashId state from this single node
|
|
@@ -207,79 +160,51 @@ module Universa
|
|
|
207
160
|
else
|
|
208
161
|
raise ArgumentError, "bad argument, want Contract or HashId"
|
|
209
162
|
end
|
|
210
|
-
ContractState.new(
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
# Execute Universa Node client protocol command with optional keyword arguments that will be passed
|
|
215
|
-
# to the node.
|
|
216
|
-
#
|
|
217
|
-
# @param [String|Symbol] name of the command
|
|
218
|
-
# @param kwargs arguments to call
|
|
219
|
-
# @return [SmartHash] with the command result
|
|
220
|
-
def execute(name, **kwargs)
|
|
221
|
-
connection.command name.to_s, *kwargs.to_a.flatten
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
# def stats days=0
|
|
225
|
-
# connection.getStats(days.to_i)
|
|
226
|
-
# end
|
|
227
|
-
|
|
228
|
-
def url
|
|
229
|
-
@node_info.url
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
def name
|
|
233
|
-
@node_info.name
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
def number
|
|
237
|
-
@node_info.number
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
def to_s
|
|
241
|
-
"Conn<#{@node_info.url}>"
|
|
163
|
+
ContractState.new(@client.getState(id))
|
|
242
164
|
end
|
|
243
165
|
|
|
244
166
|
def inspect
|
|
245
|
-
|
|
167
|
+
"<Universa::Connection:#{url}"
|
|
246
168
|
end
|
|
247
169
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
def connection
|
|
251
|
-
@connection ||= retry_with_timeout(15, 3) {
|
|
252
|
-
conn = Service.umi.instantiate("com.icodici.universa.node2.network.Client",
|
|
253
|
-
@node_info.url,
|
|
254
|
-
@client.private_key,
|
|
255
|
-
nil,
|
|
256
|
-
false)
|
|
257
|
-
.getClient(@node_info.number - 1)
|
|
258
|
-
conn
|
|
259
|
-
}
|
|
170
|
+
def to_s
|
|
171
|
+
inspect
|
|
260
172
|
end
|
|
261
173
|
|
|
262
174
|
end
|
|
263
175
|
|
|
176
|
+
# The state of some contract reported by thee network. It is a convenience wrapper around Universa
|
|
177
|
+
# ItemState structure.
|
|
264
178
|
class ContractState
|
|
265
179
|
def initialize(universa_contract_state)
|
|
266
180
|
@source = universa_contract_state
|
|
267
181
|
end
|
|
268
182
|
|
|
183
|
+
# get errors reported by the network
|
|
184
|
+
# @return [Array(String)] possibly empty array
|
|
269
185
|
def errors
|
|
270
|
-
@source.errors&.map
|
|
186
|
+
@_errors ||= @source.errors&.map(&:to_s) || []
|
|
271
187
|
rescue
|
|
272
188
|
"failed to extract errors: #$!"
|
|
273
189
|
end
|
|
274
190
|
|
|
191
|
+
# @return true if the state contain errors
|
|
192
|
+
def errors?
|
|
193
|
+
!errors.empty?
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# @return ItemState structure reported by the UMI
|
|
275
197
|
def state
|
|
276
|
-
@source.
|
|
198
|
+
@source.state
|
|
277
199
|
end
|
|
278
200
|
|
|
201
|
+
# Check that state us +PENDING+. Pending state is neither approved nor rejected.
|
|
202
|
+
# @return true if this state is one of the +PENDING+ states
|
|
279
203
|
def is_pending
|
|
280
204
|
state.start_with?('PENDING')
|
|
281
205
|
end
|
|
282
206
|
|
|
207
|
+
# @return true if the contract state was approved
|
|
283
208
|
def is_approved
|
|
284
209
|
case state
|
|
285
210
|
when 'APPROVED', 'LOCKED'
|
|
@@ -289,16 +214,18 @@ module Universa
|
|
|
289
214
|
end
|
|
290
215
|
end
|
|
291
216
|
|
|
217
|
+
# same as {is_approved}
|
|
292
218
|
def approved?
|
|
293
219
|
is_approved
|
|
294
220
|
end
|
|
295
221
|
|
|
222
|
+
# same as {pending}
|
|
296
223
|
def pending?
|
|
297
224
|
is_pending
|
|
298
225
|
end
|
|
299
226
|
|
|
300
227
|
def to_s
|
|
301
|
-
"ContractState:#{state}"
|
|
228
|
+
"<ContractState:#{state}>"
|
|
302
229
|
end
|
|
303
230
|
|
|
304
231
|
def inspect
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'forwardable'
|
|
2
2
|
require_relative './entry'
|
|
3
3
|
|
|
4
|
-
# Filesystem-based storage. See {FileStore}.
|
|
4
|
+
# Filesystem-based storage. See {FileStore}. Under reconsidering, please do not use it yet.
|
|
5
5
|
module Universa::FSStore
|
|
6
6
|
|
|
7
7
|
# Simple file-based store that could be efficiently user with per-file cloud storages like Dropbox,
|
data/lib/universa/service.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Universa
|
|
|
15
15
|
@config = SmartHash.new path: nil
|
|
16
16
|
@known_proxies = {}
|
|
17
17
|
[Contract, PrivateKey, PublicKey, KeyAddress, HashId, Binder, Role, ChangeOwnerPermission, RevokePermission,
|
|
18
|
-
SplitJoinPermission].each {|klass| register_proxy klass}
|
|
18
|
+
SplitJoinPermission, UmiClient].each {|klass| register_proxy klass}
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
# Implementation of {Service.configure}
|
|
@@ -82,8 +82,8 @@ module Universa
|
|
|
82
82
|
# the remote to create remote instance.
|
|
83
83
|
class RemoteAdapter < Delegator
|
|
84
84
|
|
|
85
|
-
# Instantiate new proxy object passing arguments to the remote constructor. The
|
|
86
|
-
#
|
|
85
|
+
# Instantiate new proxy object passing arguments to the remote constructor. The UMI host will try
|
|
86
|
+
# to find overloaded constructor that matches the arguments.
|
|
87
87
|
#
|
|
88
88
|
# @param [*Any] args any arguments that remote constructor may accept.
|
|
89
89
|
def initialize(*args)
|
data/lib/universa/umi.rb
CHANGED
|
@@ -90,6 +90,13 @@ module Universa
|
|
|
90
90
|
@version.version
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
+
# @return Universa network library core version
|
|
94
|
+
def core_version
|
|
95
|
+
@core_version ||= begin
|
|
96
|
+
invoke_static "Core", "VERSION"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
93
100
|
# Create instance of some Universa Java API class, for example 'Contract', passing any arguments
|
|
94
101
|
# to its constructor. The returned reference could be used much like local instance, nu the actual
|
|
95
102
|
# work will happen in the child process. Use references as much as possible as they take all the
|
|
@@ -235,7 +242,7 @@ module Universa
|
|
|
235
242
|
# convert ruby arguments array to corresponding UMI values
|
|
236
243
|
def prepare_args args
|
|
237
244
|
raise "pp bug" if args == [:pretty_print] # this often happens whilte tracing
|
|
238
|
-
args.map {|x| prepare x
|
|
245
|
+
args.map {|x| prepare x}
|
|
239
246
|
end
|
|
240
247
|
|
|
241
248
|
# convert single argument to UMI value to pass
|
|
@@ -246,7 +253,7 @@ module Universa
|
|
|
246
253
|
case x
|
|
247
254
|
when Array
|
|
248
255
|
# deep convert all array items
|
|
249
|
-
x.map{|a| prepare a
|
|
256
|
+
x.map {|a| prepare a}
|
|
250
257
|
when Set
|
|
251
258
|
# Make a Java Set
|
|
252
259
|
r = call("instantiate", "Set", x.to_a.map {|i| i._as_umi_arg(self)})
|
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.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- sergeych
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-
|
|
11
|
+
date: 2019-04-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: farcall
|
|
@@ -130,20 +130,22 @@ files:
|
|
|
130
130
|
- bin/setup
|
|
131
131
|
- bin/umi/bin/umi
|
|
132
132
|
- bin/umi/bin/umi.bat
|
|
133
|
+
- bin/umi/lib/com.eclipsesource.minimal-json.minimal-json-0.9.4.jar
|
|
133
134
|
- bin/umi/lib/com.fasterxml.jackson.core.jackson-annotations-2.8.11.jar
|
|
134
135
|
- bin/umi/lib/com.fasterxml.jackson.core.jackson-core-2.8.11.jar
|
|
135
136
|
- bin/umi/lib/com.fasterxml.jackson.core.jackson-databind-2.8.11.1.jar
|
|
136
137
|
- bin/umi/lib/com.fasterxml.jackson.datatype.jackson-datatype-jdk8-2.8.11.jar
|
|
137
138
|
- bin/umi/lib/com.fasterxml.jackson.datatype.jackson-datatype-jsr310-2.8.11.jar
|
|
138
|
-
- bin/umi/lib/com.icodici.common_tools-3.
|
|
139
|
-
- bin/umi/lib/com.icodici.crypto-3.
|
|
139
|
+
- bin/umi/lib/com.icodici.common_tools-3.9.9.jar
|
|
140
|
+
- bin/umi/lib/com.icodici.crypto-3.9.9.jar
|
|
140
141
|
- bin/umi/lib/com.icodici.nanohttpd-2.1.0.jar
|
|
141
|
-
- bin/umi/lib/com.icodici.umi-0.8.
|
|
142
|
-
- bin/umi/lib/com.icodici.universa_core-3.
|
|
142
|
+
- bin/umi/lib/com.icodici.umi-0.8.29.jar
|
|
143
|
+
- bin/umi/lib/com.icodici.universa_core-3.9.9.jar
|
|
143
144
|
- bin/umi/lib/com.madgag.spongycastle.core-1.58.0.0.jar
|
|
144
145
|
- bin/umi/lib/com.squareup.jnagmp.jnagmp-2.0.0.jar
|
|
145
146
|
- bin/umi/lib/com.typesafe.play.play-functional_2.12-2.6.10.jar
|
|
146
147
|
- bin/umi/lib/com.typesafe.play.play-json_2.12-2.6.10.jar
|
|
148
|
+
- bin/umi/lib/joda-time.joda-time-2.9.9.jar
|
|
147
149
|
- bin/umi/lib/net.java.dev.jna.jna-4.5.1.jar
|
|
148
150
|
- bin/umi/lib/net.java.dev.jna.jna-platform-4.5.0.jar
|
|
149
151
|
- bin/umi/lib/net.sf.jopt-simple.jopt-simple-4.9.jar
|
|
@@ -167,6 +169,7 @@ files:
|
|
|
167
169
|
- lib/universa/stored_contract.rb
|
|
168
170
|
- lib/universa/string_utils.rb
|
|
169
171
|
- lib/universa/tools.rb
|
|
172
|
+
- lib/universa/u_settings.rb
|
|
170
173
|
- lib/universa/umi.rb
|
|
171
174
|
- lib/universa/version.rb
|
|
172
175
|
- lib/universa/weak_reference.rb
|
|
Binary file
|