zold 0.29.27 → 0.29.28
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/.github/CODE_OF_CONDUCT.md +76 -0
- data/.github/CONTRIBUTING.md +11 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.rubocop.yml +6 -2
- data/README.md +107 -6
- data/fixtures/merge/legacy_negatives_stay/copies/0123456789abcdef/scores.zc +1 -1
- data/fixtures/merge/negative_overwriting/0123456789abcdef.z +6 -0
- data/fixtures/merge/negative_overwriting/146b852f2d9ad984.z +6 -0
- data/fixtures/merge/negative_overwriting/assert.rb +25 -0
- data/fixtures/merge/negative_overwriting/copies/0123456789abcdef/1.zc +6 -0
- data/fixtures/merge/negative_overwriting/copies/0123456789abcdef/scores.zc +1 -0
- data/fixtures/merge/negative_overwriting/opts +2 -0
- data/lib/zold/commands/fetch.rb +1 -1
- data/lib/zold/commands/merge.rb +6 -6
- data/lib/zold/commands/node.rb +4 -0
- data/lib/zold/commands/pay.rb +1 -0
- data/lib/zold/commands/push.rb +5 -1
- data/lib/zold/commands/remote.rb +7 -3
- data/lib/zold/commands/routines/reconcile.rb +7 -2
- data/lib/zold/commands/routines/reconnect.rb +20 -5
- data/lib/zold/commands/routines/retire.rb +48 -0
- data/lib/zold/gem.rb +1 -1
- data/lib/zold/node/farm.rb +1 -1
- data/lib/zold/node/farmers.rb +1 -1
- data/lib/zold/node/front.rb +1 -0
- data/lib/zold/patch.rb +10 -2
- data/lib/zold/remotes.rb +10 -4
- data/lib/zold/version.rb +1 -1
- data/test/commands/routines/test_reconnect.rb +2 -1
- data/test/commands/routines/test_retire.rb +40 -0
- data/test/commands/test_node.rb +1 -1
- data/test/commands/test_pay.rb +2 -1
- data/test/node/test_front.rb +1 -0
- data/zold.gemspec +13 -13
- metadata +42 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8fc5f47657b08c4e98a026b0b71def6da39a322e3f24666614a4f35d7f4580aa
|
|
4
|
+
data.tar.gz: da6bac2fdec7446e025e96ba6df2ada4a41122152eabf1f3748a0c80628d4fec
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c5c081dd571630428327bc2ae02ff0a47bab44e4d288f6ca6bfe9852cad9dd1c5300183f8c00b26de7e167af62281dcb3fc1c38691e1f656e02a3405d54fac44
|
|
7
|
+
data.tar.gz: 787d7d4d98ff67a4b26297ed3e1a3ec7dd5993e012585f2ac4755e5c69543cfb70f328497801cedb100576b3f1d70fb6ef13e71564c88d766ecb54659662d63d
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
|
8
|
+
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
|
9
|
+
level of experience, education, socio-economic status, nationality, personal
|
|
10
|
+
appearance, race, religion, or sexual identity and orientation.
|
|
11
|
+
|
|
12
|
+
## Our Standards
|
|
13
|
+
|
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
|
15
|
+
include:
|
|
16
|
+
|
|
17
|
+
* Using welcoming and inclusive language
|
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
|
19
|
+
* Gracefully accepting constructive criticism
|
|
20
|
+
* Focusing on what is best for the community
|
|
21
|
+
* Showing empathy towards other community members
|
|
22
|
+
|
|
23
|
+
Examples of unacceptable behavior by participants include:
|
|
24
|
+
|
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
|
26
|
+
advances
|
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
|
28
|
+
* Public or private harassment
|
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
|
30
|
+
address, without explicit permission
|
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
|
32
|
+
professional setting
|
|
33
|
+
|
|
34
|
+
## Our Responsibilities
|
|
35
|
+
|
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
|
38
|
+
response to any instances of unacceptable behavior.
|
|
39
|
+
|
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
|
44
|
+
threatening, offensive, or harmful.
|
|
45
|
+
|
|
46
|
+
## Scope
|
|
47
|
+
|
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
|
49
|
+
when an individual is representing the project or its community. Examples of
|
|
50
|
+
representing a project or community include using an official project e-mail
|
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
|
53
|
+
further defined and clarified by project maintainers.
|
|
54
|
+
|
|
55
|
+
## Enforcement
|
|
56
|
+
|
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
58
|
+
reported by contacting the project team at github@zold.io. All
|
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
|
63
|
+
|
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
|
66
|
+
members of the project's leadership.
|
|
67
|
+
|
|
68
|
+
## Attribution
|
|
69
|
+
|
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
|
71
|
+
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
|
72
|
+
|
|
73
|
+
[homepage]: https://www.contributor-covenant.org
|
|
74
|
+
|
|
75
|
+
For answers to common questions about this code of conduct, see
|
|
76
|
+
https://www.contributor-covenant.org/faq
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Create a report to help us improve
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Describe the bug**
|
|
11
|
+
A clear and concise description of what the bug is.
|
|
12
|
+
|
|
13
|
+
**To Reproduce**
|
|
14
|
+
Steps to reproduce the behavior:
|
|
15
|
+
1. Go to '...'
|
|
16
|
+
2. Click on '....'
|
|
17
|
+
3. Scroll down to '....'
|
|
18
|
+
4. See error
|
|
19
|
+
|
|
20
|
+
**Expected behavior**
|
|
21
|
+
A clear and concise description of what you expected to happen.
|
|
22
|
+
|
|
23
|
+
**Screenshots**
|
|
24
|
+
If applicable, add screenshots to help explain your problem.
|
|
25
|
+
|
|
26
|
+
**Desktop (please complete the following information):**
|
|
27
|
+
- OS: [e.g. iOS]
|
|
28
|
+
- Browser [e.g. chrome, safari]
|
|
29
|
+
- Version [e.g. 22]
|
|
30
|
+
|
|
31
|
+
**Smartphone (please complete the following information):**
|
|
32
|
+
- Device: [e.g. iPhone6]
|
|
33
|
+
- OS: [e.g. iOS8.1]
|
|
34
|
+
- Browser [e.g. stock browser, safari]
|
|
35
|
+
- Version [e.g. 22]
|
|
36
|
+
|
|
37
|
+
**Additional context**
|
|
38
|
+
Add any other context about the problem here.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an idea for this project
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Is your feature request related to a problem? Please describe.**
|
|
11
|
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
12
|
+
|
|
13
|
+
**Describe the solution you'd like**
|
|
14
|
+
A clear and concise description of what you want to happen.
|
|
15
|
+
|
|
16
|
+
**Describe alternatives you've considered**
|
|
17
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
|
18
|
+
|
|
19
|
+
**Additional context**
|
|
20
|
+
Add any other context or screenshots about the feature request here.
|
data/.rubocop.yml
CHANGED
|
@@ -5,12 +5,16 @@ AllCops:
|
|
|
5
5
|
DisplayCopNames: true
|
|
6
6
|
TargetRubyVersion: 2.5
|
|
7
7
|
|
|
8
|
+
Lint/ToJSON:
|
|
9
|
+
Enabled: false
|
|
10
|
+
Layout/AlignArguments:
|
|
11
|
+
Enabled: false
|
|
8
12
|
Style/ClassAndModuleChildren:
|
|
9
13
|
Enabled: false
|
|
10
14
|
Layout/EmptyLineAfterGuardClause:
|
|
11
15
|
Enabled: false
|
|
12
16
|
Metrics/CyclomaticComplexity:
|
|
13
|
-
Max:
|
|
17
|
+
Max: 33
|
|
14
18
|
Metrics/MethodLength:
|
|
15
19
|
Enabled: false
|
|
16
20
|
Layout/MultilineMethodCallIndentation:
|
|
@@ -30,7 +34,7 @@ Metrics/ParameterLists:
|
|
|
30
34
|
Layout/AlignParameters:
|
|
31
35
|
Enabled: false
|
|
32
36
|
Metrics/PerceivedComplexity:
|
|
33
|
-
Max:
|
|
37
|
+
Max: 36
|
|
34
38
|
Metrics/LineLength:
|
|
35
39
|
Max: 120
|
|
36
40
|
Style/MultilineBlockChain:
|
data/README.md
CHANGED
|
@@ -15,20 +15,39 @@
|
|
|
15
15
|
|
|
16
16
|
[](http://rubydoc.info/github/zold-io/zold/master/frames)
|
|
17
17
|
[](https://codeclimate.com/github/zold-io/zold/maintainability)
|
|
18
|
+
[](https://hitsofcode.com/github/zold-io/zold)
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
To understand what Zold cryptocurrency is about you may want
|
|
21
|
+
to watch [this video](https://youtu.be/5A9uBwMow0M) first. Then, you may
|
|
22
|
+
want to read [this blog](https://blog.zold.io/2018/07/08/mission.html) post.
|
|
23
|
+
Then, you have to read the [Green Paper](https://papers.zold.io/green-paper.pdf)
|
|
24
|
+
(just four pages). In a nutshell, Zold is a cryptocurrency with the following
|
|
25
|
+
features:
|
|
21
26
|
|
|
22
|
-
|
|
27
|
+
* No Blockchain
|
|
28
|
+
* No General Ledger
|
|
29
|
+
* Very fast, because de-centralized
|
|
30
|
+
* 100 times cheaper than Bitcoin
|
|
31
|
+
* Proof-of-work
|
|
32
|
+
* Unique consensus protocol
|
|
33
|
+
* Pre-mined with total capacity of 2 billion ZLD
|
|
34
|
+
* Anonymous
|
|
35
|
+
* Written in Ruby
|
|
36
|
+
|
|
37
|
+
More details you can find in the [White Paper](https://papers.zold.io/wp.pdf).
|
|
38
|
+
|
|
39
|
+
You can also find us at the [Bitcointalk](https://bitcointalk.org/index.php?topic=5095078) forum.
|
|
23
40
|
|
|
24
41
|
Join our [Telegram group](https://t.me/zold_io) to discuss it all live.
|
|
25
42
|
|
|
26
43
|
The license is [MIT](https://github.com/zold-io/zold/blob/master/LICENSE.txt).
|
|
27
44
|
|
|
28
|
-
The web wallet is here: [wts.zold.io](https://wts.zold.io).
|
|
29
|
-
|
|
30
45
|
## How to Use
|
|
31
46
|
|
|
47
|
+
You can try the web wallet [here](https://wts.zold.io), but the best way
|
|
48
|
+
to use Zold is through the command line tool, which has all the features
|
|
49
|
+
and should remind you Git, if you are a programmer.
|
|
50
|
+
|
|
32
51
|
First, install [Ruby 2.3+](https://www.ruby-lang.org/en/documentation/installation/),
|
|
33
52
|
[Rubygems](https://rubygems.org/pages/download), and
|
|
34
53
|
the [gem](https://rubygems.org/gems/zold).
|
|
@@ -190,7 +209,7 @@ Yes, you can run many nodes with the same wallet ID.
|
|
|
190
209
|
Yes, you can use `--threads` command line argument for your node
|
|
191
210
|
and the number of threads will be as big as you wish.
|
|
192
211
|
|
|
193
|
-
## JSON Details
|
|
212
|
+
## Front-end JSON Details
|
|
194
213
|
|
|
195
214
|
When you open up the front web page of your node, you will see a JSON document
|
|
196
215
|
with a lot of technical details. Here is the explanation of the majority of them:
|
|
@@ -271,6 +290,88 @@ To be continued...
|
|
|
271
290
|
|
|
272
291
|
`hours_alive` is the time in hours your server is alive without a reboot.
|
|
273
292
|
|
|
293
|
+
## HTTP RESTful API
|
|
294
|
+
|
|
295
|
+
Well, maybe it's not purely RESTful, but each node has a simple
|
|
296
|
+
set of HTTP entry points, which you can use to retrieve information
|
|
297
|
+
about wallets, node status, log details, and some other things. Here
|
|
298
|
+
is a more or less complete list of them:
|
|
299
|
+
|
|
300
|
+
* `GET /`: returns the JSON explained above
|
|
301
|
+
|
|
302
|
+
* `GET /score`: returns the text presentation of the current Score
|
|
303
|
+
|
|
304
|
+
* `GET /version`: returns the version of the software
|
|
305
|
+
|
|
306
|
+
* `GET /protocol`: returns the protocol ID
|
|
307
|
+
|
|
308
|
+
* `GET /wallet/ID`: returns the JSON with wallet details
|
|
309
|
+
|
|
310
|
+
* `GET /wallet/ID/balance`: returns wallet balance in zents (text/plain)
|
|
311
|
+
|
|
312
|
+
* `GET /wallet/ID/key`: returns wallet public RSA key
|
|
313
|
+
|
|
314
|
+
* `GET /wallet/ID/mtime`: returns ISO-8601 time of wallet file modification
|
|
315
|
+
|
|
316
|
+
* `GET /wallet/ID/size`: returns the size of the wallet file in bytes
|
|
317
|
+
|
|
318
|
+
* `GET /wallet/ID/age`: returns the age of the wallet, in seconds
|
|
319
|
+
|
|
320
|
+
* `GET /wallet/ID/txns`: returns the amount of transactions in the wallet
|
|
321
|
+
|
|
322
|
+
* `GET /wallet/ID/debt`: returns the tax debt of the wallet in zents
|
|
323
|
+
|
|
324
|
+
* `GET /wallet/ID/digest`: returns SHA-256 digest of the wallet file
|
|
325
|
+
|
|
326
|
+
* `GET /wallet/ID/mnemo`: returns the mnemo short string of the wallet
|
|
327
|
+
|
|
328
|
+
* `GET /wallet/ID/txns.json`: returns the full list of transactions in the wallet in JSON document
|
|
329
|
+
|
|
330
|
+
* `GET /wallet/ID.txt`: returns the text presentation of the wallet
|
|
331
|
+
|
|
332
|
+
* `GET /wallet/ID.html`: returns the HTML presentation of the wallet
|
|
333
|
+
|
|
334
|
+
* `GET /wallet/ID.bin`: returns the entire wallet file
|
|
335
|
+
|
|
336
|
+
* `GET /wallet/ID/copies`: returns the list of copies of the wallet
|
|
337
|
+
|
|
338
|
+
* `GET /wallet/ID/copy/NAME`: returns the entire content of a single copy of the wallet
|
|
339
|
+
|
|
340
|
+
* `PUT /wallet/ID`: accepts a new content of the wallet, in order to
|
|
341
|
+
modify the one stored on the server (PUSH operation)
|
|
342
|
+
|
|
343
|
+
* `GET /wallets`: returns the list of all wallets maintained by the node,
|
|
344
|
+
in plain text, separated by EOL
|
|
345
|
+
|
|
346
|
+
* `GET /remotes`: returns the list of remote nodes in JSON
|
|
347
|
+
|
|
348
|
+
* `GET /ledger`: returns the list of recently visible transactions
|
|
349
|
+
|
|
350
|
+
* `GET /ledger.json`: returns the list of recently visible transactions, in JSON
|
|
351
|
+
|
|
352
|
+
There are a few other entry points, which exist most for debugging purposes,
|
|
353
|
+
they may not be supported by alternative implementations of the node software:
|
|
354
|
+
|
|
355
|
+
* `GET /pid`: returns the process ID of the software
|
|
356
|
+
|
|
357
|
+
* `GET /trace`: returns the entire log of the node
|
|
358
|
+
|
|
359
|
+
* `GET /farm`: returns the statistics of the Farm
|
|
360
|
+
|
|
361
|
+
* `GET /metronome`: returns the statistics of the Metronome
|
|
362
|
+
|
|
363
|
+
* `GET /threads`: returns the statistics of all Ruby threads
|
|
364
|
+
|
|
365
|
+
* `GET /ps`: returns the statistics of all currently running Unix processes
|
|
366
|
+
|
|
367
|
+
* `GET /queue`: returns the statistics of the node queue
|
|
368
|
+
|
|
369
|
+
* `GET /journal`: returns the journal, in HTML
|
|
370
|
+
|
|
371
|
+
* `GET /journal/item?id=ID`: returns the content of a single journal entry
|
|
372
|
+
|
|
373
|
+
There could be other entry points, not documented here.
|
|
374
|
+
|
|
274
375
|
## SDK
|
|
275
376
|
|
|
276
377
|
Here is how you use Zold SDK from your Ruby app. First, you should
|
|
@@ -1 +1 @@
|
|
|
1
|
-
1,0.0.0.0,4096,10,NOW,
|
|
1
|
+
1,0.0.0.0,4096,10,NOW,
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
test
|
|
2
|
+
2
|
|
3
|
+
0123456789abcdef
|
|
4
|
+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnppnkzrCreiKaHF09XKS6bO+2274+wSGo+F8KHvVrNbqear/e09r9PB/P6bFdLoMh4Xc7p/7+NSEZLeu2Eg/dBkQLEb8M/zgkT4gBDGyETW/zusYHIznX/lgf0f8qleIQIIB/3Y7QpDztkamWYTKWlnmlrcQvCVB0uRRPm4ZMcMJouKR9n7E2DpL9eolKyOwr/JY08iJOuK3HuW6tRdvE+0x7I+wDprM65OH/PoArlfO5qnIGbeXwsEGRXt0w6a/ubPpeadFjPXotE7cT1SA4YSD1tWTIVm1ZWppOE967XoDIum6tzt5KfzDNRfs9GbCfO0BL235HxbO8I9rTlVLTKcNAiEe0CWolY9HR5pMaosOgZ6PB54InJEZJs4L2b10c+IlVUX1RSnwfFYg0vy5oqrYyqt7gnipl/06YW4PKIYc7TljogsEHf9Cz/kpEKzqDtsH2LrmjMNsbWiousvNHM+MPgcuMg8ZnwLKwDy9NWdI4XLTpg6hVRJNH9erZdfAO5tg/3ub3JLeJbyNo4Bd5f/Bnr5YN/9ahZ87kSpI7v0Qk94dR4hDPjstEcghyZ9RVUoN52+h1g83cd3cIqksJd0kifMCoBmObD013RSPQqNwr9GGU2JaJEm25Vq35dy2DHAkOQpUZVT8GNg9IM4qUDV0yagTN3bZyvuLWIgufb0CAwEAAQ==
|
|
5
|
+
|
|
6
|
+
0001;2018-01-01T01:01:01Z;ffffffe000000000;qJkKMWUC;146b852f2d9ad984;test;j9ozyBTjJ90TK1u3o4m6ueLWspbXCgEWhLYNQ8B9EonQ9bIsl19DbdsPwyY5M3o8dSefDOwsA9OE48x9ncyh3n/BSYKSUHzSrU1RmVLR2+hveEzwGKPZleUzurDbKZA06MuuP46KDv3uhJ9OjX6szVwBqHorxoJ0zyqRtRdjKop7gqTVbyIIGOM5fu4lx3KhdWJLzD0sN75rdCmuF2yw/V2D+AdkB+84C+rTjp4x9bUr5zIinQtAYn8AJbdpk/3CLHWR/RhqFdUmQrQlgLile016bfkKg8l2S7HufrKdGNVThuoOrpTKZV+prctV2f8/2XANrHoVrtT5y3aENXfvlvYMQYqJsOl8wvLtQEts4pwtQBOdKUC4i82aZW/3lkQr9T8JPoyIthmm8AoOAx6RU0ccDckarDYAg1t5nYA/wK+fBDFkwIwUoI6zkvmwpUCI6/Wf9smF69H+FQNi8OrH0MaO0nzh7zFxgpFKaJAGumEvGPtA7rY3zYZ0P4lK9QnIa887p8WgA7YCN9/WieY71DINfMjVRwC7kxCa7LqNtOlXyp2pMJzWGWGbZH/SF6HpeIMbq7J0yUrdyLz8OwgLk5Wzuv/mht+mvhbI54mZixs4MawAXs9kTPmqGIRpMFvqLmD6GtKEltKuHGnAs4QSFjMmWbGG0WS98TztzFMpLG0=
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
test
|
|
2
|
+
2
|
|
3
|
+
146b852f2d9ad984
|
|
4
|
+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyevqT0h4CcDkA4jeC+u0ITqULIyKD4HlUTyoOl8QK6BqDZ5oc4jCIGHgVfwdRVhKdUukWb7AUIVPVf76qepNZLwQ8UGtEwk+nCfq0/4u4zlCr78ZMmpIbdme5a6rXjiB3TE8UVgTPROx5EecazKXcvgmqfl7o98QBkqSKVqvIHzED5wADQzxjmGMmLWP8aTs0/6v4NG7wXJnMEJ0QYf845HMjpiXlNgldU1M1gTCM/8RJJaGjbEOax8HWj4n7LnqPHL5wtSe0CI6BzQsm9lEHUyywMW+SleCc5yponz5ZPzVkMYIzvO36BqykeZ0AXJyE5JfMoljJXG5bJX4tMhvIDVlZDlDh07vd11x3qJEtKB0c/hYcUmrUMAr0jZXBjv+MVq3WMVMClrMDyc1LMmrGh7Jp4hyugYRmrRAiTiZvmd2MaVB16sU91aiDHo90MefQ+RTwGO0YDNDzW1jW0qEYlfXZQGALWDWnyP1h1qzu4SaWrp4Chnt5OmwV67gxUw/VKQekTaiN7/ApeB5wXakrZiuIITi39865qqkkjDWVrRneqF0YDZz1S7eOIZ3OJvCi5OMU1nTTxaycVofolVmfGZlWROS9ENj2gVk9RQLX9xBXC1Vk4C/U7bIPDhk+nMHaDriuTNlmRPwMa6Flj1A9cLDUFPu7F0rDv3iqJkKMWUCAwEAAQ==
|
|
5
|
+
|
|
6
|
+
0001;2019-05-14T14:34:56Z;0000001000000000;v4NG7wXJ;0123456789abcdef;test;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2018-2019 Zerocracy, Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
require_relative 'asserts'
|
|
24
|
+
wallet = Zold::Wallet.new('0123456789abcdef.z')
|
|
25
|
+
assert_equal(Zold::Amount.new(zld: -16.0), wallet.balance)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
test
|
|
2
|
+
1
|
|
3
|
+
0123456789abcdef
|
|
4
|
+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnppnkzrCreiKaHF09XKS6bO+2274+wSGo+F8KHvVrNbqear/e09r9PB/P6bFdLoMh4Xc7p/7+NSEZLeu2Eg/dBkQLEb8M/zgkT4gBDGyETW/zusYHIznX/lgf0f8qleIQIIB/3Y7QpDztkamWYTKWlnmlrcQvCVB0uRRPm4ZMcMJouKR9n7E2DpL9eolKyOwr/JY08iJOuK3HuW6tRdvE+0x7I+wDprM65OH/PoArlfO5qnIGbeXwsEGRXt0w6a/ubPpeadFjPXotE7cT1SA4YSD1tWTIVm1ZWppOE967XoDIum6tzt5KfzDNRfs9GbCfO0BL235HxbO8I9rTlVLTKcNAiEe0CWolY9HR5pMaosOgZ6PB54InJEZJs4L2b10c+IlVUX1RSnwfFYg0vy5oqrYyqt7gnipl/06YW4PKIYc7TljogsEHf9Cz/kpEKzqDtsH2LrmjMNsbWiousvNHM+MPgcuMg8ZnwLKwDy9NWdI4XLTpg6hVRJNH9erZdfAO5tg/3ub3JLeJbyNo4Bd5f/Bnr5YN/9ahZ87kSpI7v0Qk94dR4hDPjstEcghyZ9RVUoN52+h1g83cd3cIqksJd0kifMCoBmObD013RSPQqNwr9GGU2JaJEm25Vq35dy2DHAkOQpUZVT8GNg9IM4qUDV0yagTN3bZyvuLWIgufb0CAwEAAQ==
|
|
5
|
+
|
|
6
|
+
0001;2019-05-14T14:34:56Z;fffffff000000000;v4NG7wXJ;146b852f2d9ad984;test;NSOdJUTYidOne3T0VranU9H8Lb4weJQ1KYhMu7MfFTIiUWXc56O4c/cRIikjQ+EFsneFtYBEHs0TH2oevndGyrHcHkBkmsMRWD0ujYFD27oWEuOX828dYM/vjn7q1ggb9XTJN3kEKnrP8zbfVzJotsh2I9ctNByGoy33ecGfYtv7pFfcUItjd6SbYmGGOCt/Jf4/I5p+pgW2xGjG75jRMQ1Gh40aWGHfOxi38HyUqSr9pcymerbUaEKpFrk8+CJ3LbCUN9Ve2WYIwIZd9POpN2PH+aF+syzEv2Yj7LDTfkLQHLzIJJqtCJvSXeqKgVKQLmtkjgHDX6aTyb8w7+NJ2Mkjq6mREny8qbJnwLi+d7Pl+fFCArP3kFBULKQDzqe7sA8+xew6Dq8kVZWoBtuPFusMhBu7rq573waOcj6ZiW7tKww0abTGe96KUNssMhyF4alHvXQ0b7orK6l2DOBV/JDlgP5mEu2mOJ8Y81peCMNa1m8Y+AgrGijrm5aqk0JHjGH2hVRrHPZcyyO+msoLe7vP5umpf4DuMBMPgGZQc5Sqpc8wuSgD+XaiSVKv1Nr/gQYp2oZbGXnGl47reCvy1lJr2kBzLIWIPdrZIGh7iVy/DFcvw+t7wvoOm1fEfVfDgl04yHwNOiUOLKNlfGFliWJoCJ+sJv5DztHpDEKLBv4=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1,0.0.0.0,4096,50,NOW,M
|
data/lib/zold/commands/fetch.rb
CHANGED
|
@@ -138,7 +138,7 @@ run 'zold remote update' or use --tolerate-quorum=1"
|
|
|
138
138
|
end
|
|
139
139
|
end
|
|
140
140
|
@log.info("#{done.value} copies of #{id} fetched in #{Age.new(start)} with the total score of \
|
|
141
|
-
#{total.value} from #{nodes.value
|
|
141
|
+
#{total.value} from #{nodes.value - masters.value}+#{masters.value}m nodes")
|
|
142
142
|
list = cps.all.map do |c|
|
|
143
143
|
" ##{c[:name]}: #{c[:score]} #{c[:total]}n #{Wallet.new(c[:path]).mnemo} \
|
|
144
144
|
#{Size.new(File.size(c[:path]))}/#{Age.new(File.mtime(c[:path]))}#{c[:master] ? ' master' : ''}"
|
data/lib/zold/commands/merge.rb
CHANGED
|
@@ -65,7 +65,7 @@ Available options:"
|
|
|
65
65
|
default: false
|
|
66
66
|
o.integer '--depth',
|
|
67
67
|
'How many levels down we try to pull other wallets if their confirmations are required (default: 0)',
|
|
68
|
-
default:
|
|
68
|
+
default: 0
|
|
69
69
|
o.bool '--allow-negative-balance',
|
|
70
70
|
'Don\'t check for the negative balance of the wallet after the merge',
|
|
71
71
|
default: false
|
|
@@ -124,7 +124,7 @@ Available options:"
|
|
|
124
124
|
wallet = Wallet.new(c[:path])
|
|
125
125
|
baseline = idx.zero? && (c[:master] || opts['edge-baseline']) && !opts['no-baseline']
|
|
126
126
|
name = "#{c[:name]}/#{idx}/#{c[:score]}#{baseline ? '/baseline' : ''}"
|
|
127
|
-
merge_one(opts, patch, wallet, name, baseline: baseline)
|
|
127
|
+
merge_one(opts, patch, wallet, name, baseline: baseline, master: c[:master])
|
|
128
128
|
score += c[:score]
|
|
129
129
|
end
|
|
130
130
|
@wallets.acq(id) do |w|
|
|
@@ -152,11 +152,11 @@ into #{@wallets.acq(id, &:mnemo)} in #{Age.new(start, limit: 0.1 + cps.count * 0
|
|
|
152
152
|
modified
|
|
153
153
|
end
|
|
154
154
|
|
|
155
|
-
def merge_one(opts, patch, wallet, name, baseline: false)
|
|
155
|
+
def merge_one(opts, patch, wallet, name, baseline: false, master: false)
|
|
156
156
|
start = Time.now
|
|
157
|
-
@log.debug("
|
|
157
|
+
@log.debug("Adding copy ##{name}#{master ? ' (master)' : ''} to the patch #{wallet.mnemo}...")
|
|
158
158
|
if opts['depth'].positive?
|
|
159
|
-
patch.join(wallet, ledger: opts['ledger'], baseline: baseline) do |txn|
|
|
159
|
+
patch.join(wallet, ledger: opts['ledger'], baseline: baseline, master: master) do |txn|
|
|
160
160
|
trusted = IO.read(opts['trusted']).split(',')
|
|
161
161
|
if trusted.include?(txn.bnf.to_s)
|
|
162
162
|
@log.debug("Won't PULL #{txn.bnf} since it is already trusted, among #{trusted.count} others")
|
|
@@ -176,7 +176,7 @@ into #{@wallets.acq(id, &:mnemo)} in #{Age.new(start, limit: 0.1 + cps.count * 0
|
|
|
176
176
|
true
|
|
177
177
|
end
|
|
178
178
|
else
|
|
179
|
-
patch.join(wallet, ledger: opts['ledger'], baseline: baseline) do |txn|
|
|
179
|
+
patch.join(wallet, ledger: opts['ledger'], baseline: baseline, master: master) do |txn|
|
|
180
180
|
@log.debug("Paying wallet #{txn.bnf} is incomplete but there is not enough depth to PULL: #{txn.to_text}")
|
|
181
181
|
false
|
|
182
182
|
end
|
data/lib/zold/commands/node.rb
CHANGED
|
@@ -457,9 +457,13 @@ the node won\'t connect to the network like that; try to do "zold remote reset"
|
|
|
457
457
|
end
|
|
458
458
|
require_relative 'routines/spread'
|
|
459
459
|
metronome.add(Routines::Spread.new(opts, @wallets, @remotes, @copies, log: @log))
|
|
460
|
+
require_relative 'routines/retire'
|
|
461
|
+
metronome.add(Routines::Retire.new(opts, log: @log))
|
|
460
462
|
if @remotes.master?(host, port)
|
|
461
463
|
require_relative 'routines/reconcile'
|
|
462
464
|
metronome.add(Routines::Reconcile.new(opts, @wallets, @remotes, @copies, "#{host}:#{port}", log: @log))
|
|
465
|
+
else
|
|
466
|
+
@log.info('This is not master, no need to reconcile')
|
|
463
467
|
end
|
|
464
468
|
@log.info('Metronome started (use --no-metronome to disable it)')
|
|
465
469
|
metronome
|
data/lib/zold/commands/pay.rb
CHANGED
|
@@ -148,6 +148,7 @@ the difference is #{(amount - from.balance).to_i} zents"
|
|
|
148
148
|
@log.debug("Keygap \"#{'*' * opts['keygap'].length}\" injected into the RSA private key")
|
|
149
149
|
end
|
|
150
150
|
key = Zold::Key.new(text: pem)
|
|
151
|
+
from.refurbish
|
|
151
152
|
txn = from.sub(amount, invoice, key, details, time: Txn.parse_time(opts['time']))
|
|
152
153
|
@log.debug("#{amount} sent from #{from} to #{txn.bnf}: #{details}")
|
|
153
154
|
@log.debug("Don't forget to do 'zold push #{from}'")
|
data/lib/zold/commands/push.rb
CHANGED
|
@@ -31,6 +31,7 @@ require_relative '../thread_pool'
|
|
|
31
31
|
require_relative '../hands'
|
|
32
32
|
require_relative '../age'
|
|
33
33
|
require_relative '../size'
|
|
34
|
+
require_relative '../tax'
|
|
34
35
|
require_relative '../log'
|
|
35
36
|
require_relative '../id'
|
|
36
37
|
require_relative '../http'
|
|
@@ -98,6 +99,9 @@ Available options:"
|
|
|
98
99
|
@wallets.acq(id) do |wallet|
|
|
99
100
|
raise "The wallet #{id} is absent at #{wallet.path}" unless wallet.exists?
|
|
100
101
|
end
|
|
102
|
+
if @wallets.acq(id) { |w| Tax.new(w).in_debt? }
|
|
103
|
+
@log.info("Taxes in #{id} are not paid, most likely the wallet won't be accepted by any node")
|
|
104
|
+
end
|
|
101
105
|
start = Time.now
|
|
102
106
|
total = Concurrent::AtomicFixnum.new
|
|
103
107
|
nodes = Concurrent::AtomicFixnum.new
|
|
@@ -121,7 +125,7 @@ Available options:"
|
|
|
121
125
|
run 'zold remote update' or use --tolerate-quorum=1"
|
|
122
126
|
end
|
|
123
127
|
end
|
|
124
|
-
@log.info("Push finished to #{done.value
|
|
128
|
+
@log.info("Push finished to #{done.value - masters.value}+#{masters.value}m nodes \
|
|
125
129
|
out of #{nodes.value} in #{Age.new(start)}, total score for #{id} is #{total.value}")
|
|
126
130
|
end
|
|
127
131
|
|
data/lib/zold/commands/remote.rb
CHANGED
|
@@ -261,7 +261,8 @@ Available options:"
|
|
|
261
261
|
@remotes.remove(r[:host], r[:port]) if !opts['masters-too'] || !r[:master]
|
|
262
262
|
@log.debug("#{r[:host]}:#{r[:port]} removed because of #{r[:errors]} errors (over #{opts['tolerate']})")
|
|
263
263
|
end
|
|
264
|
-
@log.info("The list of #{all.count} remotes trimmed down to #{@remotes.all.count} nodes
|
|
264
|
+
@log.info("The list of #{all.count} remotes trimmed down to #{@remotes.all.count} nodes \
|
|
265
|
+
(#{@remotes.all.count { |r| r[:master] }} masters)")
|
|
265
266
|
end
|
|
266
267
|
|
|
267
268
|
def update(opts)
|
|
@@ -299,7 +300,9 @@ Available options:"
|
|
|
299
300
|
if total.zero?
|
|
300
301
|
@log.info("The list of remotes is #{Rainbow('empty').red}, run 'zold remote reset'!")
|
|
301
302
|
else
|
|
302
|
-
@log.info("There are #{total} known remotes
|
|
303
|
+
@log.info("There are #{total} known remotes \
|
|
304
|
+
(#{@remotes.all.count { |r| r[:master] }} masters) \
|
|
305
|
+
with the overall score of \
|
|
303
306
|
#{@remotes.all.map { |r| r[:score] }.inject(&:+)}, after update in #{Age.new(st)}")
|
|
304
307
|
end
|
|
305
308
|
end
|
|
@@ -354,7 +357,8 @@ it's recommended to reboot, but I don't do it because of --never-reboot")
|
|
|
354
357
|
@remotes.remove(r[:host], r[:port])
|
|
355
358
|
@log.debug("Remote #{r[:host]}:#{r[:port]}/#{r[:score]}/#{r[:errors]}e removed from the list")
|
|
356
359
|
end
|
|
357
|
-
@log.info("#{@remotes.all.count} best remote nodes were selected to stay in the list
|
|
360
|
+
@log.info("#{@remotes.all.count} best remote nodes were selected to stay in the list \
|
|
361
|
+
(#{@remotes.all.count { |r| r[:master] }} masters)")
|
|
358
362
|
end
|
|
359
363
|
|
|
360
364
|
def terminate
|
|
@@ -48,10 +48,15 @@ class Zold::Routines::Reconcile
|
|
|
48
48
|
next if r.to_mnemo == @address
|
|
49
49
|
res = r.http('/wallets').get
|
|
50
50
|
r.assert_code(200, res)
|
|
51
|
-
res.body.strip.split("\n").compact
|
|
51
|
+
missing = res.body.strip.split("\n").compact
|
|
52
52
|
.select { |i| /^[a-f0-9]{16}$/.match?(i) }
|
|
53
53
|
.reject { |i| @wallets.acq(Zold::Id.new(i), &:exists?) }
|
|
54
|
-
|
|
54
|
+
missing.each { |i| pull(i) }
|
|
55
|
+
if missing.empty?
|
|
56
|
+
log.info("Nothing to reconcile with #{r}, we are good at #{@address}")
|
|
57
|
+
else
|
|
58
|
+
@log.info("Reconcile routine pulled #{missing.count} wallets from #{r}")
|
|
59
|
+
end
|
|
55
60
|
end
|
|
56
61
|
end
|
|
57
62
|
|
|
@@ -44,16 +44,31 @@ class Zold::Routines::Reconnect
|
|
|
44
44
|
score = @farm.best[0]
|
|
45
45
|
args << "--ignore-node=#{Shellwords.escape("#{score.host}:#{score.port}")}" if score
|
|
46
46
|
cmd.run(args + ['masters']) unless @opts['routine-immediately']
|
|
47
|
-
|
|
48
|
-
return if @opts['routine-immediately'] && all.empty?
|
|
47
|
+
return if @opts['routine-immediately'] && @remotes.all.empty?
|
|
49
48
|
cmd.run(args + ['select'])
|
|
50
|
-
if
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
if (step % 10).zero?
|
|
50
|
+
@log.info("It is round ##{step}, time to update the list of remotes")
|
|
51
|
+
update(cmd, args)
|
|
52
|
+
end
|
|
53
|
+
if @remotes.all.any? { |r| r[:errors] > Zold::Remotes::TOLERANCE }
|
|
54
|
+
@log.info('There are a few remote nodes with too many errors, it\'s time to update')
|
|
55
|
+
update(cmd, args)
|
|
56
|
+
else
|
|
57
|
+
@log.debug("All #{@remotes.all.count} remote nodes are still more or less error-free, won't update")
|
|
58
|
+
end
|
|
59
|
+
if @remotes.all.count < Zold::Remotes::MAX_NODES / 2
|
|
60
|
+
@log.info("There are just #{@remotes.all.count} remotes in the list, time to update")
|
|
61
|
+
update(cmd, args)
|
|
53
62
|
end
|
|
54
63
|
cmd.run(args + ['trim'])
|
|
55
64
|
cmd.run(args + ['select'])
|
|
56
65
|
@log.info("Reconnected, there are #{@remotes.all.count} remote notes: \
|
|
57
66
|
#{@remotes.all.map { |r| "#{r[:host]}:#{r[:port]}/#{r[:score]}/#{r[:errors]}" }.join(', ')}")
|
|
58
67
|
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def update(cmd, args)
|
|
72
|
+
cmd.run(args + ['update'] + (@opts['never-reboot'] ? [] : ['--reboot']))
|
|
73
|
+
end
|
|
59
74
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2018-2019 Zerocracy, Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
require 'shellwords'
|
|
24
|
+
require_relative '../routines'
|
|
25
|
+
require_relative '../remote'
|
|
26
|
+
require_relative '../../node/farm'
|
|
27
|
+
|
|
28
|
+
# Kill the node if it's too old.
|
|
29
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
30
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
|
31
|
+
# License:: MIT
|
|
32
|
+
class Zold::Routines::Retire
|
|
33
|
+
def initialize(opts, log: Log::NULL)
|
|
34
|
+
@opts = opts
|
|
35
|
+
@log = log
|
|
36
|
+
@start = Time.now
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def exec(step = 0)
|
|
40
|
+
sleep(60) unless @opts['routine-immediately']
|
|
41
|
+
days = 4
|
|
42
|
+
return if step < days * 24 * 60 && Time.now - @start < days * 24 * 60 * 60
|
|
43
|
+
return if @opts['never-reboot']
|
|
44
|
+
@log.info("We are too old, step ##{step}, it's time to retire (use --never-reboot to avoid this)")
|
|
45
|
+
require_relative '../../node/front'
|
|
46
|
+
Zold::Front.stop!
|
|
47
|
+
end
|
|
48
|
+
end
|
data/lib/zold/gem.rb
CHANGED
data/lib/zold/node/farm.rb
CHANGED
data/lib/zold/node/farmers.rb
CHANGED
|
@@ -111,7 +111,7 @@ for #{score.value}/#{score.strength} at #{score.host}:#{score.port}")
|
|
|
111
111
|
begin
|
|
112
112
|
buffer << stdout.read_nonblock(16 * 1024)
|
|
113
113
|
# rubocop:disable Lint/HandleExceptions
|
|
114
|
-
rescue IO::WaitReadable
|
|
114
|
+
rescue IO::WaitReadable
|
|
115
115
|
# rubocop:enable Lint/HandleExceptions
|
|
116
116
|
# nothing to do here
|
|
117
117
|
rescue StandardError => e
|
data/lib/zold/node/front.rb
CHANGED
|
@@ -232,6 +232,7 @@ this is not a normal behavior, you may want to report a bug to our GitHub reposi
|
|
|
232
232
|
total_mem: total_mem,
|
|
233
233
|
threads: "#{Thread.list.select { |t| t.status == 'run' }.count}/#{Thread.list.count}",
|
|
234
234
|
wallets: total_wallets,
|
|
235
|
+
journal: DirItems.new(settings.journal_dir).fetch.count,
|
|
235
236
|
remotes: all_remotes.count,
|
|
236
237
|
nscore: all_remotes.map { |r| r[:score] }.inject(&:+) || 0,
|
|
237
238
|
farm: settings.farm.to_json,
|
data/lib/zold/patch.rb
CHANGED
|
@@ -69,7 +69,10 @@ module Zold
|
|
|
69
69
|
# The "baseline" flag, when set to TRUE, means that we should NOT validate
|
|
70
70
|
# the presence of positive incoming transactions in their correspondent
|
|
71
71
|
# wallets. We shall just trust them.
|
|
72
|
-
|
|
72
|
+
#
|
|
73
|
+
# If the "master" flag is set, this copy is coming from a master node
|
|
74
|
+
# and we should allow it to overwrite negative transactions.
|
|
75
|
+
def join(wallet, ledger: '/dev/null', baseline: false, master: false)
|
|
73
76
|
if @id.nil?
|
|
74
77
|
@id = wallet.id
|
|
75
78
|
@key = wallet.key
|
|
@@ -95,11 +98,16 @@ module Zold
|
|
|
95
98
|
seen += 1
|
|
96
99
|
if txn.amount.negative?
|
|
97
100
|
dup = @txns.find { |t| t.id == txn.id && t.amount.negative? }
|
|
98
|
-
if dup
|
|
101
|
+
if dup && !master
|
|
99
102
|
@log.error("An attempt to overwrite existing transaction #{dup.to_text.inspect} \
|
|
100
103
|
with a new one #{txn.to_text.inspect} from #{wallet.mnemo}")
|
|
101
104
|
next
|
|
102
105
|
end
|
|
106
|
+
if dup && master
|
|
107
|
+
@log.debug("An overwrite to the existing transaction #{dup.to_text.inspect} \
|
|
108
|
+
is coming from a master node: #{txn.to_text.inspect} from #{wallet.mnemo}")
|
|
109
|
+
@txns.reject! { |t| t.id == txn.id && t.amount.negative? }
|
|
110
|
+
end
|
|
103
111
|
unless Signature.new(@network).valid?(@key, wallet.id, txn)
|
|
104
112
|
@log.error("Invalid RSA signature at the transaction ##{txn.id} of #{wallet.id}: #{txn.to_text.inspect}")
|
|
105
113
|
next
|
data/lib/zold/remotes.rb
CHANGED
|
@@ -34,6 +34,7 @@ require_relative 'http'
|
|
|
34
34
|
require_relative 'hands'
|
|
35
35
|
require_relative 'thread_pool'
|
|
36
36
|
require_relative 'node/farm'
|
|
37
|
+
require_relative 'commands/fetch'
|
|
37
38
|
|
|
38
39
|
# The list of remotes.
|
|
39
40
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
@@ -118,7 +119,12 @@ at #{response.headers['X-Zold-Path']}"
|
|
|
118
119
|
MAX_NODES = 16
|
|
119
120
|
|
|
120
121
|
# Default nodes and their ports
|
|
121
|
-
MASTERS = CSV.read(File.expand_path(File.join(File.dirname(__FILE__), '../../resources/masters')))
|
|
122
|
+
MASTERS = CSV.read(File.expand_path(File.join(File.dirname(__FILE__), '../../resources/masters'))).map do |r|
|
|
123
|
+
{
|
|
124
|
+
host: r[0].strip,
|
|
125
|
+
port: r[1].to_i
|
|
126
|
+
}
|
|
127
|
+
end.freeze
|
|
122
128
|
private_constant :MASTERS
|
|
123
129
|
|
|
124
130
|
# Empty, for standalone mode
|
|
@@ -168,9 +174,9 @@ at #{response.headers['X-Zold-Path']}"
|
|
|
168
174
|
def masters
|
|
169
175
|
MASTERS.each do |r|
|
|
170
176
|
if block_given?
|
|
171
|
-
next unless yield(r[
|
|
177
|
+
next unless yield(r[:host], r[:port])
|
|
172
178
|
end
|
|
173
|
-
add(r[
|
|
179
|
+
add(r[:host], r[:port])
|
|
174
180
|
end
|
|
175
181
|
end
|
|
176
182
|
|
|
@@ -255,7 +261,7 @@ at #{response.headers['X-Zold-Path']}"
|
|
|
255
261
|
end
|
|
256
262
|
|
|
257
263
|
def master?(host, port)
|
|
258
|
-
!MASTERS.find { |r| r[
|
|
264
|
+
!MASTERS.find { |r| r[:host] == host && r[:port] == port }.nil?
|
|
259
265
|
end
|
|
260
266
|
|
|
261
267
|
private
|
data/lib/zold/version.rb
CHANGED
|
@@ -36,7 +36,8 @@ class TestReconnect < Zold::Test
|
|
|
36
36
|
Dir.mktmpdir do |dir|
|
|
37
37
|
remotes = Zold::Remotes.new(file: File.join(dir, 'remotes.csv'))
|
|
38
38
|
remotes.clean
|
|
39
|
-
|
|
39
|
+
remotes.add('localhost', 4096)
|
|
40
|
+
stub_request(:get, 'http://localhost:4096/remotes').to_return(status: 404)
|
|
40
41
|
opts = { 'never-reboot' => true, 'routine-immediately' => true }
|
|
41
42
|
routine = Zold::Routines::Reconnect.new(opts, remotes, log: test_log)
|
|
42
43
|
routine.exec
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2018-2019 Zerocracy, Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
require 'minitest/autorun'
|
|
24
|
+
require 'tmpdir'
|
|
25
|
+
require 'webmock/minitest'
|
|
26
|
+
require_relative '../../test__helper'
|
|
27
|
+
require_relative '../../../lib/zold/remotes'
|
|
28
|
+
require_relative '../../../lib/zold/commands/routines/retire.rb'
|
|
29
|
+
|
|
30
|
+
# Retire test.
|
|
31
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
32
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
|
33
|
+
# License:: MIT
|
|
34
|
+
class TestRetire < Zold::Test
|
|
35
|
+
def test_retires
|
|
36
|
+
opts = { 'never-reboot' => false, 'routine-immediately' => true }
|
|
37
|
+
routine = Zold::Routines::Retire.new(opts, log: test_log)
|
|
38
|
+
routine.exec(10 * 24 * 60)
|
|
39
|
+
end
|
|
40
|
+
end
|
data/test/commands/test_node.rb
CHANGED
|
@@ -56,7 +56,7 @@ class TestNode < Zold::Test
|
|
|
56
56
|
wallets: wallets, copies: copies.root,
|
|
57
57
|
remotes: remotes, log: test_log
|
|
58
58
|
).run(['fetch', '--ignore-score-weakness', '--tolerate-edges', '--tolerate-quorum=1'])
|
|
59
|
-
rescue StandardError =>
|
|
59
|
+
rescue StandardError => _e
|
|
60
60
|
sleep 1
|
|
61
61
|
retry if (retries += 1) < 3
|
|
62
62
|
end
|
data/test/commands/test_pay.rb
CHANGED
|
@@ -107,8 +107,9 @@ class TestPay < Zold::Test
|
|
|
107
107
|
FakeHome.new(log: test_log).run do |home|
|
|
108
108
|
wallet = home.create_wallet
|
|
109
109
|
amount = Zold::Amount.new(zld: 2.0)
|
|
110
|
+
wallets = home.wallets
|
|
110
111
|
Threads.new(10).assert do
|
|
111
|
-
Zold::Pay.new(wallets:
|
|
112
|
+
Zold::Pay.new(wallets: wallets, copies: home.dir, remotes: home.remotes, log: test_log).run(
|
|
112
113
|
[
|
|
113
114
|
'pay', '--force', '--private-key=fixtures/id_rsa',
|
|
114
115
|
wallet.id.to_s, 'NOPREFIX@dddd0000dddd0000', amount.to_zld, '-'
|
data/test/node/test_front.rb
CHANGED
|
@@ -64,6 +64,7 @@ class FrontTest < Zold::Test
|
|
|
64
64
|
assert_equal('zold-io/zold', json['repo'])
|
|
65
65
|
assert(json['pid'].positive?, json)
|
|
66
66
|
assert(json['cpus'].positive?, json)
|
|
67
|
+
assert(!json['journal'].negative?, json)
|
|
67
68
|
assert(json['memory'].positive?, json)
|
|
68
69
|
assert(!json['load'].negative?, json)
|
|
69
70
|
assert(json['wallets'].positive?, json)
|
data/zold.gemspec
CHANGED
|
@@ -62,18 +62,18 @@ and suggests a different architecture for digital wallet maintenance.'
|
|
|
62
62
|
s.rdoc_options = ['--charset=UTF-8']
|
|
63
63
|
s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
|
|
64
64
|
s.add_runtime_dependency 'backtrace', '>=0.3'
|
|
65
|
-
s.add_runtime_dependency 'concurrent-ruby', '1.1.
|
|
66
|
-
s.add_runtime_dependency 'diffy', '3.
|
|
65
|
+
s.add_runtime_dependency 'concurrent-ruby', '1.1.5'
|
|
66
|
+
s.add_runtime_dependency 'diffy', '3.3.0'
|
|
67
67
|
s.add_runtime_dependency 'futex', '>=0.8.5'
|
|
68
68
|
s.add_runtime_dependency 'get_process_mem', '~>0.2'
|
|
69
69
|
s.add_runtime_dependency 'haml', '5.0.4'
|
|
70
|
-
s.add_runtime_dependency 'json', '2.
|
|
71
|
-
s.add_runtime_dependency 'memory_profiler', '0.9.
|
|
72
|
-
s.add_runtime_dependency 'mimic', '0.4.
|
|
70
|
+
s.add_runtime_dependency 'json', '2.2.0'
|
|
71
|
+
s.add_runtime_dependency 'memory_profiler', '0.9.13'
|
|
72
|
+
s.add_runtime_dependency 'mimic', '0.4.4'
|
|
73
73
|
s.add_runtime_dependency 'openssl', '2.1.2'
|
|
74
74
|
s.add_runtime_dependency 'rainbow', '3.0.0'
|
|
75
75
|
s.add_runtime_dependency 'semantic', '1.6.1'
|
|
76
|
-
s.add_runtime_dependency 'sinatra', '2.0.
|
|
76
|
+
s.add_runtime_dependency 'sinatra', '2.0.5'
|
|
77
77
|
s.add_runtime_dependency 'slop', '4.6.2'
|
|
78
78
|
s.add_runtime_dependency 'sys-proctable', '1.2.1'
|
|
79
79
|
s.add_runtime_dependency 'thin', '1.7.2'
|
|
@@ -83,19 +83,19 @@ and suggests a different architecture for digital wallet maintenance.'
|
|
|
83
83
|
s.add_runtime_dependency 'usagewatch_ext', '0.2.1'
|
|
84
84
|
s.add_runtime_dependency 'zache', '>=0.12'
|
|
85
85
|
s.add_runtime_dependency 'zold-score', '0.4.6'
|
|
86
|
-
s.add_development_dependency 'codecov', '0.1.
|
|
86
|
+
s.add_development_dependency 'codecov', '0.1.14'
|
|
87
87
|
s.add_development_dependency 'cucumber', '3.1.2'
|
|
88
88
|
s.add_development_dependency 'guard', '2.15.0'
|
|
89
89
|
s.add_development_dependency 'guard-minitest', '2.4.6'
|
|
90
90
|
s.add_development_dependency 'minitest', '5.11.3'
|
|
91
91
|
s.add_development_dependency 'minitest-fail-fast', '0.1.0'
|
|
92
92
|
s.add_development_dependency 'minitest-hooks', '1.5.0'
|
|
93
|
-
s.add_development_dependency 'rake', '12.3.
|
|
93
|
+
s.add_development_dependency 'rake', '12.3.2'
|
|
94
94
|
s.add_development_dependency 'random-port', '0.3.1'
|
|
95
|
-
s.add_development_dependency 'rdoc', '
|
|
96
|
-
s.add_development_dependency 'rspec-rails', '3.8.
|
|
97
|
-
s.add_development_dependency 'rubocop', '0.
|
|
98
|
-
s.add_development_dependency 'rubocop-rspec', '1.
|
|
99
|
-
s.add_development_dependency 'webmock', '3.
|
|
95
|
+
s.add_development_dependency 'rdoc', '6.1.1'
|
|
96
|
+
s.add_development_dependency 'rspec-rails', '3.8.2'
|
|
97
|
+
s.add_development_dependency 'rubocop', '0.69.0'
|
|
98
|
+
s.add_development_dependency 'rubocop-rspec', '1.33.0'
|
|
99
|
+
s.add_development_dependency 'webmock', '3.5.1'
|
|
100
100
|
s.add_development_dependency 'xcop', '>=0.6'
|
|
101
101
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zold
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.29.
|
|
4
|
+
version: 0.29.28
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yegor Bugayenko
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-
|
|
11
|
+
date: 2019-05-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: backtrace
|
|
@@ -30,28 +30,28 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - '='
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 1.1.
|
|
33
|
+
version: 1.1.5
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - '='
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 1.1.
|
|
40
|
+
version: 1.1.5
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: diffy
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - '='
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 3.
|
|
47
|
+
version: 3.3.0
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - '='
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: 3.
|
|
54
|
+
version: 3.3.0
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: futex
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -100,42 +100,42 @@ dependencies:
|
|
|
100
100
|
requirements:
|
|
101
101
|
- - '='
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: 2.
|
|
103
|
+
version: 2.2.0
|
|
104
104
|
type: :runtime
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
108
|
- - '='
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: 2.
|
|
110
|
+
version: 2.2.0
|
|
111
111
|
- !ruby/object:Gem::Dependency
|
|
112
112
|
name: memory_profiler
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
114
114
|
requirements:
|
|
115
115
|
- - '='
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: 0.9.
|
|
117
|
+
version: 0.9.13
|
|
118
118
|
type: :runtime
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
122
|
- - '='
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: 0.9.
|
|
124
|
+
version: 0.9.13
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
126
|
name: mimic
|
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
|
128
128
|
requirements:
|
|
129
129
|
- - '='
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: 0.4.
|
|
131
|
+
version: 0.4.4
|
|
132
132
|
type: :runtime
|
|
133
133
|
prerelease: false
|
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
135
|
requirements:
|
|
136
136
|
- - '='
|
|
137
137
|
- !ruby/object:Gem::Version
|
|
138
|
-
version: 0.4.
|
|
138
|
+
version: 0.4.4
|
|
139
139
|
- !ruby/object:Gem::Dependency
|
|
140
140
|
name: openssl
|
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -184,14 +184,14 @@ dependencies:
|
|
|
184
184
|
requirements:
|
|
185
185
|
- - '='
|
|
186
186
|
- !ruby/object:Gem::Version
|
|
187
|
-
version: 2.0.
|
|
187
|
+
version: 2.0.5
|
|
188
188
|
type: :runtime
|
|
189
189
|
prerelease: false
|
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
191
|
requirements:
|
|
192
192
|
- - '='
|
|
193
193
|
- !ruby/object:Gem::Version
|
|
194
|
-
version: 2.0.
|
|
194
|
+
version: 2.0.5
|
|
195
195
|
- !ruby/object:Gem::Dependency
|
|
196
196
|
name: slop
|
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -324,14 +324,14 @@ dependencies:
|
|
|
324
324
|
requirements:
|
|
325
325
|
- - '='
|
|
326
326
|
- !ruby/object:Gem::Version
|
|
327
|
-
version: 0.1.
|
|
327
|
+
version: 0.1.14
|
|
328
328
|
type: :development
|
|
329
329
|
prerelease: false
|
|
330
330
|
version_requirements: !ruby/object:Gem::Requirement
|
|
331
331
|
requirements:
|
|
332
332
|
- - '='
|
|
333
333
|
- !ruby/object:Gem::Version
|
|
334
|
-
version: 0.1.
|
|
334
|
+
version: 0.1.14
|
|
335
335
|
- !ruby/object:Gem::Dependency
|
|
336
336
|
name: cucumber
|
|
337
337
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -422,14 +422,14 @@ dependencies:
|
|
|
422
422
|
requirements:
|
|
423
423
|
- - '='
|
|
424
424
|
- !ruby/object:Gem::Version
|
|
425
|
-
version: 12.3.
|
|
425
|
+
version: 12.3.2
|
|
426
426
|
type: :development
|
|
427
427
|
prerelease: false
|
|
428
428
|
version_requirements: !ruby/object:Gem::Requirement
|
|
429
429
|
requirements:
|
|
430
430
|
- - '='
|
|
431
431
|
- !ruby/object:Gem::Version
|
|
432
|
-
version: 12.3.
|
|
432
|
+
version: 12.3.2
|
|
433
433
|
- !ruby/object:Gem::Dependency
|
|
434
434
|
name: random-port
|
|
435
435
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -450,70 +450,70 @@ dependencies:
|
|
|
450
450
|
requirements:
|
|
451
451
|
- - '='
|
|
452
452
|
- !ruby/object:Gem::Version
|
|
453
|
-
version:
|
|
453
|
+
version: 6.1.1
|
|
454
454
|
type: :development
|
|
455
455
|
prerelease: false
|
|
456
456
|
version_requirements: !ruby/object:Gem::Requirement
|
|
457
457
|
requirements:
|
|
458
458
|
- - '='
|
|
459
459
|
- !ruby/object:Gem::Version
|
|
460
|
-
version:
|
|
460
|
+
version: 6.1.1
|
|
461
461
|
- !ruby/object:Gem::Dependency
|
|
462
462
|
name: rspec-rails
|
|
463
463
|
requirement: !ruby/object:Gem::Requirement
|
|
464
464
|
requirements:
|
|
465
465
|
- - '='
|
|
466
466
|
- !ruby/object:Gem::Version
|
|
467
|
-
version: 3.8.
|
|
467
|
+
version: 3.8.2
|
|
468
468
|
type: :development
|
|
469
469
|
prerelease: false
|
|
470
470
|
version_requirements: !ruby/object:Gem::Requirement
|
|
471
471
|
requirements:
|
|
472
472
|
- - '='
|
|
473
473
|
- !ruby/object:Gem::Version
|
|
474
|
-
version: 3.8.
|
|
474
|
+
version: 3.8.2
|
|
475
475
|
- !ruby/object:Gem::Dependency
|
|
476
476
|
name: rubocop
|
|
477
477
|
requirement: !ruby/object:Gem::Requirement
|
|
478
478
|
requirements:
|
|
479
479
|
- - '='
|
|
480
480
|
- !ruby/object:Gem::Version
|
|
481
|
-
version: 0.
|
|
481
|
+
version: 0.69.0
|
|
482
482
|
type: :development
|
|
483
483
|
prerelease: false
|
|
484
484
|
version_requirements: !ruby/object:Gem::Requirement
|
|
485
485
|
requirements:
|
|
486
486
|
- - '='
|
|
487
487
|
- !ruby/object:Gem::Version
|
|
488
|
-
version: 0.
|
|
488
|
+
version: 0.69.0
|
|
489
489
|
- !ruby/object:Gem::Dependency
|
|
490
490
|
name: rubocop-rspec
|
|
491
491
|
requirement: !ruby/object:Gem::Requirement
|
|
492
492
|
requirements:
|
|
493
493
|
- - '='
|
|
494
494
|
- !ruby/object:Gem::Version
|
|
495
|
-
version: 1.
|
|
495
|
+
version: 1.33.0
|
|
496
496
|
type: :development
|
|
497
497
|
prerelease: false
|
|
498
498
|
version_requirements: !ruby/object:Gem::Requirement
|
|
499
499
|
requirements:
|
|
500
500
|
- - '='
|
|
501
501
|
- !ruby/object:Gem::Version
|
|
502
|
-
version: 1.
|
|
502
|
+
version: 1.33.0
|
|
503
503
|
- !ruby/object:Gem::Dependency
|
|
504
504
|
name: webmock
|
|
505
505
|
requirement: !ruby/object:Gem::Requirement
|
|
506
506
|
requirements:
|
|
507
507
|
- - '='
|
|
508
508
|
- !ruby/object:Gem::Version
|
|
509
|
-
version: 3.
|
|
509
|
+
version: 3.5.1
|
|
510
510
|
type: :development
|
|
511
511
|
prerelease: false
|
|
512
512
|
version_requirements: !ruby/object:Gem::Requirement
|
|
513
513
|
requirements:
|
|
514
514
|
- - '='
|
|
515
515
|
- !ruby/object:Gem::Version
|
|
516
|
-
version: 3.
|
|
516
|
+
version: 3.5.1
|
|
517
517
|
- !ruby/object:Gem::Dependency
|
|
518
518
|
name: xcop
|
|
519
519
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -550,7 +550,11 @@ extra_rdoc_files:
|
|
|
550
550
|
files:
|
|
551
551
|
- ".0pdd.yml"
|
|
552
552
|
- ".gitattributes"
|
|
553
|
+
- ".github/CODE_OF_CONDUCT.md"
|
|
554
|
+
- ".github/CONTRIBUTING.md"
|
|
553
555
|
- ".github/ISSUE_TEMPLATE.md"
|
|
556
|
+
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
|
557
|
+
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
|
554
558
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|
|
555
559
|
- ".gitignore"
|
|
556
560
|
- ".pdd"
|
|
@@ -600,6 +604,12 @@ files:
|
|
|
600
604
|
- fixtures/merge/missed_wallets/copies/0123456789abcdef/1.zc
|
|
601
605
|
- fixtures/merge/missed_wallets/copies/0123456789abcdef/scores.zc
|
|
602
606
|
- fixtures/merge/missed_wallets/opts
|
|
607
|
+
- fixtures/merge/negative_overwriting/0123456789abcdef.z
|
|
608
|
+
- fixtures/merge/negative_overwriting/146b852f2d9ad984.z
|
|
609
|
+
- fixtures/merge/negative_overwriting/assert.rb
|
|
610
|
+
- fixtures/merge/negative_overwriting/copies/0123456789abcdef/1.zc
|
|
611
|
+
- fixtures/merge/negative_overwriting/copies/0123456789abcdef/scores.zc
|
|
612
|
+
- fixtures/merge/negative_overwriting/opts
|
|
603
613
|
- fixtures/merge/negatives_in_between/0000000000000000.z
|
|
604
614
|
- fixtures/merge/negatives_in_between/0123456789abcdef.z
|
|
605
615
|
- fixtures/merge/negatives_in_between/assert.rb
|
|
@@ -664,6 +674,7 @@ files:
|
|
|
664
674
|
- lib/zold/commands/routines/gc.rb
|
|
665
675
|
- lib/zold/commands/routines/reconcile.rb
|
|
666
676
|
- lib/zold/commands/routines/reconnect.rb
|
|
677
|
+
- lib/zold/commands/routines/retire.rb
|
|
667
678
|
- lib/zold/commands/routines/spread.rb
|
|
668
679
|
- lib/zold/commands/show.rb
|
|
669
680
|
- lib/zold/commands/taxes.rb
|
|
@@ -721,6 +732,7 @@ files:
|
|
|
721
732
|
- test/commands/routines/test_gc.rb
|
|
722
733
|
- test/commands/routines/test_reconcile.rb
|
|
723
734
|
- test/commands/routines/test_reconnect.rb
|
|
735
|
+
- test/commands/routines/test_retire.rb
|
|
724
736
|
- test/commands/test_alias.rb
|
|
725
737
|
- test/commands/test_calculate.rb
|
|
726
738
|
- test/commands/test_clean.rb
|
|
@@ -801,7 +813,7 @@ licenses:
|
|
|
801
813
|
- MIT
|
|
802
814
|
metadata: {}
|
|
803
815
|
post_install_message: |-
|
|
804
|
-
Thanks for installing Zold 0.29.
|
|
816
|
+
Thanks for installing Zold 0.29.28!
|
|
805
817
|
Study our White Paper: https://papers.zold.io/wp.pdf
|
|
806
818
|
Read our blog posts: https://blog.zold.io
|
|
807
819
|
Try ZLD online wallet at: https://wts.zold.io
|
|
@@ -836,6 +848,7 @@ test_files:
|
|
|
836
848
|
- test/commands/routines/test_gc.rb
|
|
837
849
|
- test/commands/routines/test_reconcile.rb
|
|
838
850
|
- test/commands/routines/test_reconnect.rb
|
|
851
|
+
- test/commands/routines/test_retire.rb
|
|
839
852
|
- test/commands/test_alias.rb
|
|
840
853
|
- test/commands/test_calculate.rb
|
|
841
854
|
- test/commands/test_clean.rb
|