Skip to content

Commit c5d1f08

Browse files
authored
Merge branch 'master' into master
2 parents 260ade6 + 64e4aa2 commit c5d1f08

File tree

84 files changed

+8288
-1935
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+8288
-1935
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
cargo-registry
22
target
33
build
4+
node_modules
45
.idea
56
*.iml
67
.venv

Jenkinsfile.ci

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ def linuxTesting(file, env_name, network_name) {
234234

235235
sh "cp libindy/target/debug/libindy.so wrappers/java/lib"
236236
sh "cp libindy/target/debug/libindy.so wrappers/python"
237+
sh "cp libindy/target/debug/libindy.so wrappers/nodejs"
237238
sh "cp libindy/target/debug/libindy.so cli"
238239
sh "cp libindy/target/debug/libindy.so libnullpay"
239240

@@ -250,6 +251,7 @@ def linuxTesting(file, env_name, network_name) {
250251

251252
stash includes: 'wrappers/java/lib/libindy.so', name: "LibindyJavaSO${env_name}"
252253
stash includes: 'wrappers/python/libindy.so', name: "LibindyPythonSO${env_name}"
254+
stash includes: 'wrappers/nodejs/libindy.so', name: "LibindyNodejsSO${env_name}"
253255
stash includes: 'cli/libindy.so', name: "LibindyCliSO${env_name}"
254256
stash includes: 'cli/libnullpay.so', name: "LibnullpayCliSO${env_name}"
255257

@@ -282,6 +284,7 @@ def linuxTesting(file, env_name, network_name) {
282284
},
283285
"${env_name}-java-test" : { linuxModuleTesting(file, env_name, network_name, this.&linuxJavaTesting) },
284286
"${env_name}-python-test" : { linuxModuleTesting(file, env_name, network_name, this.&linuxPythonTesting) },
287+
"${env_name}-nodejs-test" : { linuxModuleTesting(file, env_name, network_name, this.&linuxNodejsTesting) },
285288
"${env_name}-cli-test" : { linuxModuleTesting(file, env_name, network_name, this.&linuxCLITesting) }
286289
])
287290
}
@@ -338,6 +341,20 @@ def linuxPythonTesting(env_name, network_name, testEnv) {
338341
}
339342
}
340343

344+
def linuxNodejsTesting(env_name, network_name, testEnv) {
345+
unstash name: "LibindyNodejsSO${env_name}"
346+
testEnv.inside("--network=${network_name}") {
347+
echo "${env_name} Libindy Test: Test nodejs wrapper"
348+
349+
sh '''
350+
cd wrappers/nodejs
351+
npm run prepare
352+
npm install
353+
LD_LIBRARY_PATH=./:${LD_LIBRARY_PATH} RUST_LOG=trace TEST_POOL_IP=10.0.0.2 npm test
354+
'''
355+
}
356+
}
357+
341358
def linuxCLITesting(env_name, network_name, testEnv) {
342359
if (env_name == "RedHat"){ // TODO: Delete it IS-702
343360
return;

cli/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ by beginning the line with a `#`.
3232

3333
### Getting help
3434
The most simple way is just start cli by `indy-cli` command and put `help` command. Also you can look to
35-
[Indy CLI Design](../doc/cli-design.md) doc that contains the list of commands and architecture overview.
35+
[Indy CLI Design](../doc/design/001-cli) doc that contains the list of commands and architecture overview.
3636

3737
### Old python-based CLI migration
3838
It is possible to import did's stored in the wallet of deprecated python-based CLI tool.

cli/src/commands/wallet.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ pub mod list_command {
161161
print_list_table(&wallets,
162162
&vec![("name", "Name"),
163163
("pool_name", "Associated pool name"),
164-
("xtype", "Type")],
164+
("type", "Type")],
165165
"There are no wallets");
166166

167167
if let Some((_, cur_wallet)) = get_opened_wallet(ctx) {
@@ -424,7 +424,7 @@ pub mod tests {
424424
{
425425
let cmd = list_command::new();
426426
let params = CommandParams::new();
427-
cmd.execute(&ctx, &params).unwrap_err();
427+
cmd.execute(&ctx, &params).unwrap();
428428
}
429429
TestUtils::cleanup_storage();
430430
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
## Legend
2+
There are some types of requests to Nodes in the Pool allowing to use StateProof optimization in Client-Node communication.
3+
Instead of sending requests to all nodes in the Pool, a client can send a request to a single Node and expect StateProof signed by BLS multi-signature.
4+
5+
BLS multi-signature (BLS MS) guaranties that there was a consensus of Nodes which signed some State identified by State RootHash.
6+
StateProof (SP) is small amount of data which allows to verify particular values against RootHash.
7+
Combination of BLS MS and SP allows clients to be sure about response of single node is a part of State signed by enough Nodes.
8+
9+
## Goals
10+
Libindy allows to extend building of supported requests via plugged interface and send them.
11+
It is nice to have a way to support BLS MS and SP verification for these plugged transactions.
12+
13+
Implementation of math for SP verification is a bit complicate for plugin logic.
14+
Therefore libindy should perform all math calculation inside.
15+
A plugin should provide handler to parse custom reply to fixed data structure.
16+
17+
## API
18+
The signature of the handler is described below together with custom `free` call to deallocate result data.
19+
20+
```rust
21+
extern fn CustomTransactionParser(reply_from_node: *const c_char, parsed_sp: *mut *const c_char) -> ErrorCode;
22+
extern fn CustomFree(data: *mut c_char) -> ErrorCode;
23+
```
24+
25+
Libindy API will contain call to register handler for specific transaction type:
26+
```rust
27+
extern fn indy_register_transaction_parser_for_sp(command_handle: i32,
28+
pool_handle: i32,
29+
txn_type: *const c_char,
30+
parser: CustomTransactionParser,
31+
free: CustomFree,
32+
cb: extern fn(command_handle_: i32, err: ErrorCode)) -> ErrorCode;
33+
```
34+
35+
### Parsed Data structure
36+
37+
A plugin should parse `reply_from_node` and return back to libindy parsed data as JSON string.
38+
Actually this data is array of entities each of them is describe SP Trie and set of key-value pairs to verify against this trie.
39+
It can be represented as `Vec<ParsedSP>` serialized to JSON.
40+
41+
42+
```rust
43+
/**
44+
Single item to verification:
45+
- SP Trie with RootHash
46+
- BLS MS
47+
- set of key-value to verify
48+
*/
49+
struct ParsedSP {
50+
/// encoded SP Trie transferred from Node to Client
51+
proof_nodes: String,
52+
/// RootHash of the Trie, start point for verification. Should be same with appropriate filed in BLS MS data
53+
root_hash: String,
54+
/// entities to verification against current SP Trie
55+
kvs_to_verify: KeyValuesInSP,
56+
/// BLS MS data for verification
57+
multi_signature: serde_json::Value,
58+
}
59+
60+
/**
61+
Variants of representation for items to verify against SP Trie
62+
Right now 2 options are specified:
63+
- simple array of key-value pair
64+
- whole subtrie
65+
*/
66+
enum KeyValuesInSP {
67+
Simple(KeyValueSimpleData),
68+
SubTrie(KeyValuesSubTrieData),
69+
}
70+
71+
/**
72+
Simple variant of `KeyValuesInSP`.
73+
74+
All required data already present in parent SP Trie (built from `proof_nodes`).
75+
`kvs` can be verified directly in parent trie
76+
*/
77+
struct KeyValueSimpleData {
78+
kvs: Vec<(String /* b64-encoded key */, Option<String /* val */>)>
79+
}
80+
81+
/**
82+
Subtrie variant of `KeyValuesInSP`.
83+
84+
In this case Client (libindy) should construct subtrie and append it into trie based on `proof_nodes`.
85+
After this preparation each kv pair can be checked.
86+
*/
87+
struct KeyValuesSubTrieData {
88+
/// base64-encoded common prefix of each pair in `kvs`. Should be used to correct merging initial trie and subtrie
89+
sub_trie_prefix: Option<String>,
90+
kvs: Vec<(String /* b64-encoded key_suffix */, Option<String /* val */>)>,
91+
}
92+
```
93+
94+
Expected libindy and plugin workflow is the following:
95+
1. Libindy receive reply from a Node, perform initial processing and pass raw reply to plugin.
96+
1. Plugin parse reply from the Node and specify one or more SP Trie with metadata and items for verification.
97+
1. Each SP Trie described by plugin as `ParsedSP`:
98+
1. Set of encoded nodes of the SP Trie, received from Node - `proof_nodes`. May be fetched from response "as is".
99+
1. RootHash of this Trie. May be fetched from the response "as is" also.
100+
1. BLS MS data. Again may be fetched from the response "as is".
101+
1. Key-value items to verification. Here plugin should define correct keys (path in the trie) and corresponded values.
102+
1. Plugin return serialized as JSON array of `ParsedSP`
103+
1. For each `ParsedSP` libindy:
104+
1. build base trie from `proof_nodes`
105+
1. if items to verify is `SubTrie`, construct this subtrie from (key-suffix, value) pairs and merge it with trie from clause above
106+
1. iterate other key-value pairs and verify that trie (with signed `root_hash`) contains `value` at specified `key`
107+
1. verify multi-signature
108+
1. If any verification is failed, libindy ignore particular SP + BLS MS and try to request same data from another node,
109+
or collect consensus of same replies from enough count of Nodes.
110+
111+
112+
Below is JSON structure for `Simple` case.
113+
```json
114+
[
115+
{
116+
"proof_nodes": "string with serialized SP tree",
117+
"root_hash": "string with root hash",
118+
"kvs_to_verify": {
119+
"type": "simple",
120+
"kvs": [["key1", "value1"], ["key2", "value2"]]
121+
},
122+
"multi_signature": "JSON object from Node`s reply as is"
123+
}
124+
]
125+
```
126+
127+
### Simple and SubTrie verification
128+
129+
Some use cases require verification multiply pairs of key-value in one Trie.
130+
Moreover there is possible situation when client would like to verify whole subtrie.
131+
In this case, the amount of data transferred from Node to Client can be significantly reduced.
132+
Instead of including all nodes for SP verification to `proof_nodes`, Node can include only prefix path down to subtrie.
133+
The entire subtrie to verification can be restored on Client side from key-value pairs and combined with prefix part.

libindy/ci/amazon.dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ RUN \
1717
libsodium-devel \
1818
spectool
1919

20+
# install nodejs and npm
21+
RUN curl --silent --location https://rpm.nodesource.com/setup_8.x | bash -
22+
RUN yum -y install nodejs
23+
2024
RUN cd /tmp && \
2125
curl https://download.libsodium.org/libsodium/releases/libsodium-1.0.14.tar.gz | tar -xz && \
2226
cd /tmp/libsodium-1.0.14 && \

libindy/ci/ubuntu.dockerfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ RUN apt-get update && \
2323
libncursesw5-dev \
2424
libzmq3-dev
2525

26+
# install nodejs and npm
27+
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
28+
RUN apt-get install -y nodejs
29+
2630
RUN pip3 install -U \
2731
pip \
2832
setuptools \
@@ -49,4 +53,4 @@ USER indy
4953
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.26.0
5054
ENV PATH /home/indy/.cargo/bin:$PATH
5155

52-
WORKDIR /home/indy
56+
WORKDIR /home/indy

libindy/include/indy_non_secrets.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ extern "C" {
1616
/// tags_json: the record tags used for search and storing meta information as json:
1717
/// {
1818
/// "tagName1": <str>, // string tag (will be stored encrypted)
19-
/// "tagName2": <int>, // int tag (will be stored encrypted)
19+
/// "tagName2": <str>, // string tag (will be stored encrypted)
2020
/// "~tagName3": <str>, // string tag (will be stored un-encrypted)
21-
/// "~tagName4": <int>, // int tag (will be stored un-encrypted)
21+
/// "~tagName4": <str>, // string tag (will be stored un-encrypted)
2222
/// }
2323
/// Note that null means no tags
2424
/// If tag name starts with "~" the tag will be stored un-encrypted that will allow
@@ -63,9 +63,9 @@ extern "C" {
6363
/// tags_json: the record tags used for search and storing meta information as json:
6464
/// {
6565
/// "tagName1": <str>, // string tag (will be stored encrypted)
66-
/// "tagName2": <int>, // int tag (will be stored encrypted)
66+
/// "tagName2": <str>, // string tag (will be stored encrypted)
6767
/// "~tagName3": <str>, // string tag (will be stored un-encrypted)
68-
/// "~tagName4": <int>, // int tag (will be stored un-encrypted)
68+
/// "~tagName4": <str>, // string tag (will be stored un-encrypted)
6969
/// }
7070
/// If tag name starts with "~" the tag will be stored un-encrypted that will allow
7171
/// usage of this tag in complex search queries (comparison, predicates)
@@ -90,9 +90,9 @@ extern "C" {
9090
/// tags_json: the record tags used for search and storing meta information as json:
9191
/// {
9292
/// "tagName1": <str>, // string tag (will be stored encrypted)
93-
/// "tagName2": <int>, // int tag (will be stored encrypted)
93+
/// "tagName2": <str>, // string tag (will be stored encrypted)
9494
/// "~tagName3": <str>, // string tag (will be stored un-encrypted)
95-
/// "~tagName4": <int>, // int tag (will be stored un-encrypted)
95+
/// "~tagName4": <str>, // string tag (will be stored un-encrypted)
9696
/// }
9797
/// If tag name starts with "~" the tag will be stored un-encrypted that will allow
9898
/// usage of this tag in complex search queries (comparison, predicates)
@@ -190,7 +190,7 @@ extern "C" {
190190
/// "tagName": "tagValue",
191191
/// $or: {
192192
/// "tagName2": { $regex: 'pattern' },
193-
/// "tagName3": { $gte: 123 },
193+
/// "tagName3": { $gte: '123' },
194194
/// },
195195
/// }
196196
/// options_json: //TODO: FIXME: Think about replacing by bitmaks

0 commit comments

Comments
 (0)