zold 0.13.43 → 0.13.44

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7c1b984c84978412b1cbbc753771396705f0d544
4
- data.tar.gz: 653f5e746fbae90ab0609915452eb646e49d86d9
3
+ metadata.gz: bf5190e58996ff52177172576009917026da5136
4
+ data.tar.gz: 7f0ce81b3a4ae8b21eb835cd6eb2d0e6aecd2aee
5
5
  SHA512:
6
- metadata.gz: 7aa48a078b7b037d165eae145f995ce886fb62f3bfe7d0f8b3e6fac984c80b02c6d4c0c5afc51f0c7411d9de28f6e0a607818043bd6c66f8fff4a38b82690784
7
- data.tar.gz: 31e5789f3c7bc710b3ee970376c40c140f0d73251ebd0a182e5acf7185ea4e9b0ed94f82b753722d8ca5824fd68274d997d26fe4e7d9038324181d6ffd65b65a
6
+ metadata.gz: a8e5c2b7ed530521fc5d3f8bda21b3f547a3a8757e3e4fa083be4b1cbf3cb59e793514d8ea85feb3f4a195e0e398312956bc7b7fa5b0c0f1587250d61a278bfd
7
+ data.tar.gz: a64b280273fcfae4bccf039b01419450065757cc8d3de53e88435864f3f026b6c2f49778c2d5b9dbe3565172681906a893fc4c3adfb04b3eee77675daef0a276
data/README.md CHANGED
@@ -18,7 +18,7 @@
18
18
  **NOTICE**: It's an experiment and a very early draft! Please, feel free to
19
19
  submit your ideas and/or pull requests.
20
20
 
21
- Here is the [White Paper](https://github.com/zold-io/papers/raw/master/wp.pdf).
21
+ Here is the [White Paper](https://papers.zold.io/wp.pdf).
22
22
 
23
23
  Join our [Telegram group](https://t.me/zold_io) to discuss it all live.
24
24
 
@@ -0,0 +1,34 @@
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'minitest'
22
+
23
+ # Test only module
24
+ module Assertions
25
+ extend Minitest::Assertions
26
+ class << self
27
+ attr_accessor :assertions
28
+ end
29
+ self.assertions = 0
30
+ end
31
+
32
+ def assert_equal(a, b)
33
+ Assertions.assert_equal(a, b)
34
+ end
@@ -0,0 +1,51 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ 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
51
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCemmeTOsKt6IpocXT1cpLps77bbvj7BIaj4Xwoe9Ws1up5qv97T2v08H8/psV0ugyHhdzun/v41IRkt67YSD90GRAsRvwz/OCRPiAEMbIRNb/O6xgcjOdf+WB/R/yqV4hAggH/djtCkPO2RqZZhMpaWeaWtxC8JUHS5FE+bhkxwwmi4pH2fsTYOkv16iUrI7Cv8ljTyIk64rce5bq1F28T7THsj7AOmszrk4f8+gCuV87mqcgZt5fCwQZFe3TDpr+5s+l5p0WM9ei0TtxPVIDhhIPW1ZMhWbVlamk4T3rtegMi6bq3O3kp/MM1F+z0ZsJ87QEvbfkfFs7wj2tOVUtMpw0CIR7QJaiVj0dHmkxqiw6Bno8HngickRkmzgvZvXRz4iVVRfVFKfB8ViDS/LmiqtjKq3uCeKmX/Tphbg8ohhztOWOiCwQd/0LP+SkQrOoO2wfYuuaMw2xtaKi6y80cz4w+By4yDxmfAsrAPL01Z0jhctOmDqFVEk0f16tl18A7m2D/e5vckt4lvI2jgF3l/8Gevlg3/1qFnzuRKkju/RCT3h1HiEM+Oy0RyCHJn1FVSg3nb6HWDzdx3dwiqSwl3SSJ8wKgGY5sPTXdFI9Co3Cv0YZTYlokSbblWrfl3LYMcCQ5ClRlVPwY2D0gzipQNXTJqBM3dtnK+4tYiC59vQ== yegor@be.Dlink
@@ -0,0 +1,6 @@
1
+ test
2
+ 1
3
+ 0000000000000000
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-06-22T07:38:23Z;fffffe0000000000;g6hVRJNH;0123456789abcdef;To help you;IFQvo0PN3JkpkuZRjPyQ6BywuM9aSRFI6GdNOevSQxWJMwSesYp6b25KIi78TcIV9b84f0Qr96d8TgvkTjLqczvZZzyYIJ+e2w8qQhbxSiCgFxfThm6U8NnrXNprMBRHg4amV40dAjgW2lfVDDRk+RtCYEUEZDX5xPhiCHC8lhtoJm/atgJfgOIAfeLTy6ZWwC+teMtHUt6/uHH9z9giYnWHLBpYFyjYSSlrf4K/0e86Kzy/8Bwmk9Q/I6Yvo7IWL7TNN5vCGiz74R2wUTHVfmlY/YdXD15JnPmmZGjoR+BCjxbpjPqYWGm2bTxSuDHCFg0oTKAHIPqC57hKzGQUNzmoSqMHxTBDTvdLHjf0Uo9oaWhdT+BTpnGzFJxgz7d9oJOsIFqrLzPZ6VjOqKtl+ptbFkrjpq9ZdfpbzzBxHhLU8quxmBihodxBZAI6f2rpDGgnwS/D2v+Ncdcmqpdin1GkU0lAeAzWhenKBqu2t9C5UeZbjw6diiKyrGPHWLS9X9BGX9j6STMyI93f81Y6+j798gqv+XZtsohxL/sHDNJK0m81S6QWnAD//bZbNqW85y8ZMFwHmn3GXsSDupaQGpe6wpvFknWxho4vM8A/nAk20rWur5PF1S4RpFwpOr/4RmBA06yWnPxdB6x9lonPKmYC5Pck0fwxXDOEcjMTdWo=
@@ -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;2018-06-22T07:38:23Z;0000020000000000;g6hVRJNH;0000000000000000;To help you;
@@ -0,0 +1,23 @@
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require_relative 'asserts.rb'
22
+ wallet = Zold::Wallet.new(Zold::Id.new('0123456789abcdef'))
23
+ assert_equal(Zold::Amount.new(zld: 388.0), wallet.balance)
@@ -0,0 +1,7 @@
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;2018-06-22T08:26:19Z;fffffff000000000;TESTPREFIX;ffffffffffffffff;For pizza;L1MFiKqM8O6Eg/v54TD7M48gI/oq7iYYmjM7cKgUpMUk7dx48K+9DRQ2as+d2SrMMH/TKdJ/It8v8DJN6RV3kVtpdZo7CsUrUisive5rpJduO68+nJFr3TB3vQrCPm8N3Cz9vfmM68WrmskPHOABETyIC9cSQrSIvaCWhchwru7sO0625y2aYiMVoW2jmKFTtflGr6M9n7rqTkaYG/EftrNMrJS7PaG19T1HOQupAcKQ4DzBujEnbm3KQQc9Rp5GR8cb49Y38IAr9lENkDB1zmMaVJeZNEyX0ne6S1ZB7Ys9L0jUIJA+SRzNHDEdWC6lcOifcCuanU4kBPFtOiuAjghJX09l8Ue1pyE478+Sy8BgApqKu1l4+p+qUSXOTx7yKwT9ahZaA9DgVHEinz6MqhiozDddw24fXRK956pQ+jUPzNJXVeH4UrDcUDAaCIX8jCaaqGQUqhJXH2KF0Z1PtWBfHYB7OxXEpiVVtScMQ+68iB40p71f7j4YrVW50G89NrCJbOamdai+3dmwiIZzSOsSahB8kXrkaF+lrDZiwNPfL2ixs3F2xW34aKHvA/UCCo7PVfUVDLC8VHiDtAKTSyoqhPP4ocomszfRaRGxSjDIh3ceCrPH9BIW2zfUzkU63+dJ5adS+XSXzO3L3gfwiLM6XPr2jlJbPy1OSMkDK7s=
7
+ 0001;2018-06-22T07:38:23Z;0000020000000000;g6hVRJNH;0000000000000000;To help you;
@@ -0,0 +1,7 @@
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
+ 0002;2018-06-22T08:26:36Z;ffffffe000000000;TESTPREFIX;eeeeeeeeeeeeeeee;For coffee;ctLF7pKtNHLoaVmsSdPTjfilp0GIdP4EVCCnQs39j6AIAYJtr0342rfMmql8piCrPn/TbnrL835QwohFHolH44ygTRgcQ2ZCSVvK49M+FekPg25S38jZEGQvBiIEdw4y/DyOW7pQLCubIqZZdbuUHuR4S5InI+sFm+IlMaKPaJ3NoOo6dgX+XC+cxJqhM8e8L/Sy2s3smNvPKjy3FVh5vEeharoov6frQztLABwFIJIGMGI6xDCfZO0lh6X3FjCCwtrtMK0pY2cYHNZS3GzMtvpQE0sNPIAjujjI/Sz8bTOLqaRSD+8SjR24DRDq4nD90L74NbbxwFaypFyhVIryAzetZs+AIhkf7hDVnh3GtzfoqIQKOzQPFV6oV4ciFSR5oiT6yt89xxeKhHTKD/E1nw0xltZ+SiqVH9Ha/8NEn5wJEeko5h+fnDL+1yVziQy9gMC1Dh/pnZgMn8T7k2Ecif3knxZf+NAoCvFRyueFzZM7S7xDs9krxc56EnZaLo7/pJ6jVuXLQlXnMgzPrbx8mJSjUQY6X2yNe5qVFauSwH6JAa0ewZm5H8n0dsHT0bKHxV+eRcFFh/g3z6LEwxxCN6KrLnPr3x66NntCEom3B+y6WCPnpa9gKSHu1caLuSoSbJ1R8Rtx1iqQN3iHlVIbHpiy3xTbfXKiwS17KZV46yA=
7
+ 0001;2018-06-22T07:38:23Z;0000020000000000;g6hVRJNH;0000000000000000;To help you;
@@ -0,0 +1,7 @@
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
+ 0003;2018-06-22T08:26:54Z;fffffff800000000;TESTPREFIX;eeeeeeeeeeeeeeee;For fun;TMrg2FZY8HJHTq7FM0VAMSTzMd3WFpUtI0naaR58pEpC/kSXM820bwIkErFW6Ymie03baRoB7BHnqrJjhCN57KkrK0LUr+FMQNbkPfbhqWnws0X/+HIcSTEdWozkc/t/I4xD2dGHUqbjJRPU87KfbmadVLwZx9TO5bL0ywBGZbV8di+GgQ7/NDdmyIWE/bkW/t3rErfNEYu0X3pyj41T02MwgETNyZTvfzhZWXFD2fooJ3qFIdw8kLoNY2RJkCwpxeJMAyeFvEWi9D5LoSO2VWw7okZylkA4TiwfDByPip9ABu4ekR7lq1MIL1RxswwwwQLiBi0VrvV3tN4VXTpaBYQTjuEh7mC3IwuK84Q29o1QX8sVcihnrwYDuUohx7D3HdSTxoV8EFsWmAaSHMwQn9xhb4hAkbS5Zv9qUvsjjBcdf9jhFTo/ecT17pdav5fZ+lxx7+fYVklJK/J9z7ZXKphOfbQ3Jg5oeOO4kuAcpSRjd2SAHySzsf06xfa5L32ZDcLorqVZC5GUdikHHVc889HeZbWNkPbGbCleK2ICwGh5b+eW1KAygtXrehhJiJVJfCPlxpFk172DdZf9Rxfs5QKdH4QTIt3xztAdU6BwZ7nwpejyz7hbgou1XqqCcaZEkMD3vMOBGurBfKFpCgX+YYsxMphmw9QSNi1D/WnSkvE=
7
+ 0001;2018-06-22T07:38:23Z;0000020000000000;g6hVRJNH;0000000000000000;To help you;
@@ -0,0 +1,7 @@
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
+ 0004;2018-06-22T08:27:06Z;ffffffc000000000;TESTPREFIX;eeeeeeeeeeeeeeee;For something else;K0V9Hfv9vAhe2QlCq69RI55bAI0RFHTaDrZFaY9pGiQT6vQV5cri19XhI6BC2i9qWUqIhEL2ikaPGZ5ODqu4rt6BBQcb/OOwZU21lPEcdm/n8HCsitPzGDX/hGjWg/ab88mFw5qLB6pasadtvjDoTG/5dBoB5rk9Ujy2c5JPpiXGR8OqF2bUsMVmUXSEKFmAK3u/EgrcApz4kFezcCriZ4lwqjgyT7grbyZXyGu8AA+AhX3zq/tyiuNJbHCrsnuWedxa9DtlTQy0/qg3JT2xPcruxoBe6ijjPbalMwWI41jt5Bp+wNUaFm94kc2cB+gyxQPf7vtHgVv5C9ikMO4XMF9b3PBVCB4i7J6b+U+PCHG4m/EA9c+PZvJSVc2cV+Ya8YTL+yTXiXOGpzvjateDwatyKjE5yA5G8yfxrtPDwuWslhT//kSHFuwpUGwZnTL4q769Wy/lEQM2uLWlD0GJ+mb/PZ6n5YhbGsgUAFiV2h93x1g3u0JKykP8/E758ZGWPMoivdxKm+dhRjNjh8jQ89Kt8UkGsD3vhi4pkSkm6vXQ8q/tq9ul6R3Is8FVAU2V9vThI/GZmT+BMUHsrMnpXEQEoBMQSMMcaSpK4hwRfpYmpC7NKBDUoSQhIcMumsXvDQaJKybKqC1BO1y3t9L7OX0Ev/fJawcDY4sJgptq7JQ=
7
+ 0001;2018-06-22T07:38:23Z;0000020000000000;g6hVRJNH;0000000000000000;To help you;
@@ -0,0 +1,7 @@
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
+ 0005;2018-06-22T08:27:22Z;fffffffc00000000;TESTPREFIX;eeeeeeeeeeeeeeee;For my friend;WF/xCNKtRpzm2DPlFAOsxHKCw6hg5Nrn3M78cNSpoaEQRPDCaPeLrQiOkLaseqPB3xk//F74qJv4EcKsjlWsgH+eQ9PQ7pp1+4pnEqff1fXcb6M5vxIa8BMMYfbcPyWIIDtAyHSn/8t35r/Zanua0tcH0FfGLzfUfGK4jK9s49rLPkEDVGjKGJPS0zaJP4a3DWclohGvU1+t2EGNk09niDKhtZKjv6YRk9t11kK76zsWj8Zc9NVxthpGavRgsrGSP7jPsMsLdPYnEGXberO1Iexl5FHG/Gc8+kj/qUcGZv3f06vfkbGbAgknibufv8uAD1OVcptjp+M55HcWyFXJhvI2OIDoyQv1RIUiL26X0b3qAOEqKEXnnAA5FbD7RlanJ3Jl+IzDKYrocE5mWvrK36w31meTReJH8I1bX8XK4TIHJNXh8xi2LK1fUZ8Crxg8pPxLgvrgfk8AR9sOS+vC5tmbWsuP1EDSwD6wB9TYGbacgpSd3Yzz8DEOvNykJoEpEUku4MLeJzYQPC7n1GWoO7ysFDr+BXiFd7d+xdfUnDK8UiiT2AecUpnnNr4fjuWfa5OTbcYmKQ34Ys3ddNc47Vc9+Eax8Q1qnEZs5lMiyA7r7gkPQSKMP17L9NyYPMOwzLvspmUzgK8vDylTHW3uGNb86dzyqKkXeA+fs7AmjTs=
7
+ 0001;2018-06-22T07:38:23Z;0000020000000000;g6hVRJNH;0000000000000000;To help you;
@@ -0,0 +1,5 @@
1
+ 1,0.0.0.0,4096,10,2018-06-21T03:41:21Z
2
+ 2,0.0.0.0,4096,20,2018-06-21T03:41:21Z
3
+ 3,0.0.0.0,4096,30,2018-06-21T03:41:21Z
4
+ 4,0.0.0.0,4096,40,2018-06-21T03:41:21Z
5
+ 5,0.0.0.0,4096,50,2018-06-21T03:41:21Z
@@ -0,0 +1,6 @@
1
+ test
2
+ 1
3
+ 0000000000000000
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-06-22T07:38:23Z;fffffe0000000000;g6hVRJNH;0123456789abcdef;To help you;IFQvo0PN3JkpkuZRjPyQ6BywuM9aSRFI6GdNOevSQxWJMwSesYp6b25KIi78TcIV9b84f0Qr96d8TgvkTjLqczvZZzyYIJ+e2w8qQhbxSiCgFxfThm6U8NnrXNprMBRHg4amV40dAjgW2lfVDDRk+RtCYEUEZDX5xPhiCHC8lhtoJm/atgJfgOIAfeLTy6ZWwC+teMtHUt6/uHH9z9giYnWHLBpYFyjYSSlrf4K/0e86Kzy/8Bwmk9Q/I6Yvo7IWL7TNN5vCGiz74R2wUTHVfmlY/YdXD15JnPmmZGjoR+BCjxbpjPqYWGm2bTxSuDHCFg0oTKAHIPqC57hKzGQUNzmoSqMHxTBDTvdLHjf0Uo9oaWhdT+BTpnGzFJxgz7d9oJOsIFqrLzPZ6VjOqKtl+ptbFkrjpq9ZdfpbzzBxHhLU8quxmBihodxBZAI6f2rpDGgnwS/D2v+Ncdcmqpdin1GkU0lAeAzWhenKBqu2t9C5UeZbjw6diiKyrGPHWLS9X9BGX9j6STMyI93f81Y6+j798gqv+XZtsohxL/sHDNJK0m81S6QWnAD//bZbNqW85y8ZMFwHmn3GXsSDupaQGpe6wpvFknWxho4vM8A/nAk20rWur5PF1S4RpFwpOr/4RmBA06yWnPxdB6x9lonPKmYC5Pck0fwxXDOEcjMTdWo=
@@ -0,0 +1,5 @@
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
+
@@ -0,0 +1,23 @@
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require_relative 'asserts'
22
+ wallet = Zold::Wallet.new(Zold::Id.new('0123456789abcdef'))
23
+ assert_equal(Zold::Amount.new(zld: 512.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;2018-06-22T07:38:23Z;0000020000000000;g6hVRJNH;0000000000000000;To help you;
@@ -0,0 +1 @@
1
+ 1,0.0.0.0,4096,50,2018-06-21T03:41:21Z
@@ -51,13 +51,13 @@ Available options:"
51
51
  mine = Args.new(opts, @log).take || return
52
52
  mine = @wallets.all if mine.empty?
53
53
  mine.map { |i| Id.new(i) }.each do |id|
54
- clean(Copies.new(File.join(@copies, id)), opts)
54
+ clean(Copies.new(File.join(@copies, id), log: @log), opts)
55
55
  end
56
56
  end
57
57
 
58
58
  def clean(cps, _)
59
- cps.clean
60
- @log.debug("Expired local copies removed for #{cps}, \
59
+ deleted = cps.clean
60
+ @log.debug("#{deleted} expired local copies removed for #{cps}, \
61
61
  #{cps.all.count} left")
62
62
  end
63
63
  end
@@ -72,8 +72,8 @@ Available options:"
72
72
  cps = cps.all.sort_by { |c| c[:score] }.reverse
73
73
  patch = Patch.new(@wallets, log: @log)
74
74
  cps.each do |c|
75
- merge_one(opts, patch, Wallet.new(c[:path]), "#{c[:host]}:#{c[:port]}")
76
- @log.debug("#{c[:host]}:#{c[:port]} merged: #{patch}")
75
+ merge_one(opts, patch, Wallet.new(c[:path]), c[:name])
76
+ @log.debug("Copy ##{c[:name]} merged: #{patch}")
77
77
  end
78
78
  wallet = @wallets.find(id)
79
79
  if wallet.exists?
@@ -84,7 +84,7 @@ Available options:"
84
84
  end
85
85
  modified = patch.save(wallet.path, overwrite: true)
86
86
  if modified
87
- @log.debug("#{cps.count} copies merged successfully into #{wallet.path}")
87
+ @log.debug("#{cps.count} copies merged successfully into #{wallet.id}, balance is #{wallet.balance}")
88
88
  else
89
89
  @log.debug("Nothing changed in #{wallet.id} after merge of #{cps.count} copies")
90
90
  end
@@ -94,7 +94,7 @@ Available options:"
94
94
  def merge_one(opts, patch, wallet, name)
95
95
  patch.join(wallet, !opts['no-baseline'])
96
96
  rescue StandardError => e
97
- @log.error("Can't merge a copy coming from #{name}: #{e.message}")
97
+ @log.error("Can't merge copy ##{name}: #{e.message}")
98
98
  @log.debug(Backtrace.new(e).to_s)
99
99
  end
100
100
  end
@@ -38,9 +38,9 @@ module Zold
38
38
  end
39
39
 
40
40
  def run(args = [])
41
+ Zold::Clean.new(wallets: @wallets, copies: @copies, log: @log).run(args)
41
42
  Zold::Fetch.new(wallets: @wallets, remotes: @remotes, copies: @copies, log: @log).run(args)
42
43
  Zold::Merge.new(wallets: @wallets, copies: @copies, log: @log).run(args)
43
- Zold::Clean.new(wallets: @wallets, copies: @copies, log: @log).run(args)
44
44
  end
45
45
  end
46
46
  end
data/lib/zold/copies.rb CHANGED
@@ -21,6 +21,7 @@
21
21
  require 'time'
22
22
  require 'csv'
23
23
  require_relative 'atomic_file'
24
+ require_relative 'log'
24
25
 
25
26
  # The list of copies.
26
27
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -29,8 +30,12 @@ require_relative 'atomic_file'
29
30
  module Zold
30
31
  # All copies
31
32
  class Copies
32
- def initialize(dir)
33
+ def initialize(dir, log: Log::Quiet.new)
34
+ raise 'Dir can\'t be nil' if dir.nil?
33
35
  @dir = dir
36
+ raise 'Log can\'t be nil' if log.nil?
37
+ @log = log
38
+ @mutex = Mutex.new
34
39
  end
35
40
 
36
41
  def root
@@ -42,16 +47,27 @@ module Zold
42
47
  end
43
48
 
44
49
  def clean
45
- list = load
46
- list.reject! { |s| s[:time] < Time.now - 24 * 60 * 60 }
47
- save(list)
48
- Dir.new(@dir).select { |f| f =~ /^[0-9]+$/ }.each do |f|
49
- File.delete(File.join(@dir, f)) if list.find { |s| s[:name] == f }.nil?
50
+ @mutex.synchronize do
51
+ list = load
52
+ list.reject! { |s| s[:time] < Time.now - 24 * 60 * 60 }
53
+ save(list)
54
+ deleted = 0
55
+ Dir.new(@dir).select { |f| f =~ /^[0-9]+$/ }.each do |f|
56
+ next unless list.find { |s| s[:name] == f }.nil?
57
+ file = File.join(@dir, f)
58
+ size = File.size(file)
59
+ File.delete(file)
60
+ @log.debug("Copy ##{f} deleted: #{size}b")
61
+ deleted += 1
62
+ end
63
+ deleted
50
64
  end
51
65
  end
52
66
 
53
67
  def remove(host, port)
54
- save(load.reject { |s| s[:host] == host && s[:port] == port })
68
+ @mutex.synchronize do
69
+ save(load.reject { |s| s[:host] == host && s[:port] == port })
70
+ end
55
71
  end
56
72
 
57
73
  # Returns the name of the copy
@@ -63,47 +79,49 @@ module Zold
63
79
  raise "Time must be in the past: #{time}" if time > Time.now
64
80
  raise 'Score must be Integer' unless score.is_a?(Integer)
65
81
  raise "Score can't be negative: #{score}" if score < 0
66
- FileUtils.mkdir_p(@dir)
67
- list = load
68
- target = list.find do |s|
69
- f = File.join(@dir, s[:name])
70
- File.exist?(f) && AtomicFile.new(f).read == content
71
- end
72
- if target.nil?
73
- max = Dir.new(@dir)
74
- .select { |f| f =~ /^[0-9]+$/ }
75
- .map(&:to_i)
76
- .max
77
- max = 0 if max.nil?
78
- name = (max + 1).to_s
79
- AtomicFile.new(File.join(@dir, name)).write(content)
80
- else
81
- name = target[:name]
82
+ @mutex.synchronize do
83
+ FileUtils.mkdir_p(@dir)
84
+ list = load
85
+ target = list.find do |s|
86
+ f = File.join(@dir, s[:name])
87
+ File.exist?(f) && AtomicFile.new(f).read == content
88
+ end
89
+ if target.nil?
90
+ max = Dir.new(@dir)
91
+ .select { |f| f =~ /^[0-9]+$/ }
92
+ .map(&:to_i)
93
+ .max
94
+ max = 0 if max.nil?
95
+ name = (max + 1).to_s
96
+ AtomicFile.new(File.join(@dir, name)).write(content)
97
+ else
98
+ name = target[:name]
99
+ end
100
+ list.reject! { |s| s[:host] == host && s[:port] == port }
101
+ list << {
102
+ name: name,
103
+ host: host,
104
+ port: port,
105
+ score: score,
106
+ time: time
107
+ }
108
+ save(list)
109
+ name
82
110
  end
83
- list.reject! { |s| s[:host] == host && s[:port] == port }
84
- list << {
85
- name: name,
86
- host: host,
87
- port: port,
88
- score: score,
89
- time: time
90
- }
91
- save(list)
92
- name
93
111
  end
94
112
 
95
113
  def all
96
- load.group_by { |s| s[:name] }.map do |name, scores|
97
- {
98
- name: name,
99
- host: scores[0][:host],
100
- port: scores[0][:port],
101
- path: File.join(@dir, name),
102
- score: scores.select { |s| s[:time] > Time.now - 24 * 60 * 60 }
103
- .map { |s| s[:score] }
104
- .inject(&:+) || 0
105
- }
106
- end.select { |c| File.exist?(c[:path]) }
114
+ @mutex.synchronize do
115
+ load.group_by { |s| s[:name] }.map do |name, scores|
116
+ {
117
+ name: name,
118
+ path: File.join(@dir, name),
119
+ score: scores.select { |s| s[:time] > Time.now - 24 * 60 * 60 }
120
+ .map { |s| s[:score] }
121
+ .inject(&:+) || 0
122
+ }
123
+ end.select { |c| File.exist?(c[:path]) }
124
+ end
107
125
  end
108
126
 
109
127
  private
@@ -48,6 +48,8 @@ module Zold
48
48
  @address = address
49
49
  raise 'Log can\'t be nil' if log.nil?
50
50
  @log = log
51
+ @history = []
52
+ @mutex = Mutex.new
51
53
  end
52
54
 
53
55
  def start
@@ -55,7 +57,9 @@ module Zold
55
57
  end
56
58
 
57
59
  def to_json
58
- {}
60
+ {
61
+ history: @history.join(', ')
62
+ }
59
63
  end
60
64
 
61
65
  # Returns a list of modifed wallets (as Zold::Id)
@@ -77,9 +81,15 @@ module Zold
77
81
  ).run(['merge', id.to_s, '--no-baseline'])
78
82
  Clean.new(wallets: @wallets, copies: copies.root, log: @log).run(['clean', id.to_s])
79
83
  copies.remove(localhost, Remotes::PORT)
80
- unless modified.empty?
81
- @log.info("Accepted #{id} in #{(Time.now - start).round(2)}s \
82
- and modified #{modified.join(', ')}")
84
+ sec = (Time.now - start).round(2)
85
+ if modified.empty?
86
+ @log.info("Accepted #{id} in #{sec}s and not modified anything")
87
+ else
88
+ @log.info("Accepted #{id} in #{sec}s and modified #{modified.join(', ')}")
89
+ end
90
+ @mutex.synchronize do
91
+ @history.shift if @history.length > 16
92
+ @history << "#{id}/#{sec}/#{modified.count}"
83
93
  end
84
94
  modified
85
95
  end
data/lib/zold/patch.rb CHANGED
@@ -40,7 +40,7 @@ module Zold
40
40
  end
41
41
 
42
42
  def to_s
43
- return 'empty' if @txns.empty?
43
+ return 'empty patch' if @txns.empty?
44
44
  "#{@txns.count} txns"
45
45
  end
46
46
 
@@ -61,14 +61,9 @@ module Zold
61
61
  end
62
62
  raise 'Public key mismatch' if wallet.key != @key
63
63
  raise "Wallet ID mismatch: #{@id} != #{wallet.id}" if wallet.id != @id
64
- max = @txns.select { |t| t.amount.negative? }.map(&:id).max.to_i
65
64
  wallet.txns.each do |txn|
66
65
  next if @txns.find { |t| t == txn }
67
66
  if txn.amount.negative?
68
- if txn.id <= max
69
- @log.error("Transaction ID is not greater than max ID #{max}: #{txn.to_text}")
70
- next
71
- end
72
67
  dup = @txns.find { |t| t.id == txn.id && t.amount.negative? }
73
68
  if dup
74
69
  @log.error("An attempt to overwrite #{dup.to_text} with this: #{txn.to_text}")
@@ -100,8 +95,8 @@ among #{payer.txns.count} transactions: #{txn.to_text}")
100
95
  next
101
96
  end
102
97
  end
103
- @log.debug("Merged on top: #{txn.to_text}")
104
98
  @txns << txn
99
+ @log.debug("Merged on top, balance is #{@txns.map(&:amount).inject(&:+)}: #{txn.to_text}")
105
100
  end
106
101
  end
107
102
 
data/lib/zold/version.rb CHANGED
@@ -23,5 +23,5 @@
23
23
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
24
24
  # License:: MIT
25
25
  module Zold
26
- VERSION = '0.13.43'.freeze
26
+ VERSION = '0.13.44'.freeze
27
27
  end
@@ -19,6 +19,7 @@
19
19
  # SOFTWARE.
20
20
 
21
21
  require 'minitest/autorun'
22
+ require 'tmpdir'
22
23
  require 'time'
23
24
  require 'webmock/minitest'
24
25
  require_relative '../test__helper'
@@ -121,4 +122,22 @@ class TestMerge < Minitest::Test
121
122
  assert_equal(Zold::Amount::ZERO, main.balance)
122
123
  end
123
124
  end
125
+
126
+ def test_merges_scenarios
127
+ base = 'fixtures/merge'
128
+ Dir.new(base).select { |f| File.directory?(File.join(base, f)) && !f.start_with?('.') }.each do |f|
129
+ Dir.mktmpdir 'test' do |dir|
130
+ FileUtils.cp_r(File.join('fixtures/merge', "#{f}/."), dir)
131
+ FileUtils.cp('fixtures/merge/asserts.rb', dir)
132
+ wallets = Zold::Wallets.new(dir)
133
+ copies = File.join(dir, 'copies')
134
+ Zold::Merge.new(wallets: wallets, copies: copies, log: test_log).run(
135
+ %w[merge 0123456789abcdef]
136
+ )
137
+ Dir.chdir(dir) do
138
+ require File.join(dir, 'assert.rb')
139
+ end
140
+ end
141
+ end
142
+ end
124
143
  end
@@ -51,10 +51,18 @@ class TestEntrance < Minitest::Test
51
51
  FakeHome.new.run do |home|
52
52
  source = home.create_wallet(sid)
53
53
  home.create_wallet(tid)
54
- modified = Zold::Entrance.new(home.wallets, home.remotes, home.copies(source).root, 'x', log: test_log).push(
55
- source.id, body
56
- )
54
+ e = Zold::Entrance.new(home.wallets, home.remotes, home.copies(source).root, 'x', log: test_log)
55
+ modified = e.push(source.id, body)
57
56
  assert_equal(2, modified.count)
58
57
  end
59
58
  end
59
+
60
+ def test_renders_json
61
+ FakeHome.new.run do |home|
62
+ wallet = home.create_wallet
63
+ e = Zold::Entrance.new(home.wallets, home.remotes, home.copies.root, 'x', log: test_log)
64
+ e.push(wallet.id, File.read(wallet.path))
65
+ assert(e.to_json[:history].include?(wallet.id.to_s))
66
+ end
67
+ end
60
68
  end
@@ -147,7 +147,7 @@ class FrontTest < Minitest::Test
147
147
  "Expected HTTP 200 OK: Found #{response.code}"
148
148
  )
149
149
  assert_operator(
150
- 700, :>, response['content-length'].to_i,
150
+ 750, :>, response['content-length'].to_i,
151
151
  'Expected the content to be smaller than 600 bytes for gzip'
152
152
  )
153
153
  end
data/test/test_amount.rb CHANGED
@@ -19,7 +19,6 @@
19
19
  # SOFTWARE.
20
20
 
21
21
  require 'minitest/autorun'
22
- require 'tmpdir'
23
22
  require_relative '../lib/zold/amount'
24
23
 
25
24
  # Amount test.
data/test/test_zold.rb CHANGED
@@ -31,8 +31,7 @@ require_relative '../lib/zold/version'
31
31
  # License:: MIT
32
32
  class TestZold < Minitest::Test
33
33
  def test_all_scripts
34
- Dir.new('fixtures/scripts').each.select { |f| f =~ /\.sh$/ && !f.start_with?('_') }.each do |f|
35
- next unless f == 'redeploy-on-upgrade.sh'
34
+ Dir.new('fixtures/scripts').select { |f| f =~ /\.sh$/ && !f.start_with?('_') }.each do |f|
36
35
  Dir.mktmpdir 'test' do |dir|
37
36
  FileUtils.cp('fixtures/id_rsa.pub', dir)
38
37
  FileUtils.cp('fixtures/id_rsa', dir)
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.13.43
4
+ version: 0.13.44
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-21 00:00:00.000000000 Z
11
+ date: 2018-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -327,6 +327,23 @@ files:
327
327
  - fixtures/keys/1.pub
328
328
  - fixtures/keys/2
329
329
  - fixtures/keys/2.pub
330
+ - fixtures/merge/asserts.rb
331
+ - fixtures/merge/id_rsa
332
+ - fixtures/merge/id_rsa.pub
333
+ - fixtures/merge/random-expenses/0000000000000000
334
+ - fixtures/merge/random-expenses/0123456789abcdef
335
+ - fixtures/merge/random-expenses/assert.rb
336
+ - fixtures/merge/random-expenses/copies/0123456789abcdef/1
337
+ - fixtures/merge/random-expenses/copies/0123456789abcdef/2
338
+ - fixtures/merge/random-expenses/copies/0123456789abcdef/3
339
+ - fixtures/merge/random-expenses/copies/0123456789abcdef/4
340
+ - fixtures/merge/random-expenses/copies/0123456789abcdef/5
341
+ - fixtures/merge/random-expenses/copies/0123456789abcdef/scores
342
+ - fixtures/merge/simple-case/0000000000000000
343
+ - fixtures/merge/simple-case/0123456789abcdef
344
+ - fixtures/merge/simple-case/assert.rb
345
+ - fixtures/merge/simple-case/copies/0123456789abcdef/1
346
+ - fixtures/merge/simple-case/copies/0123456789abcdef/scores
330
347
  - fixtures/scripts/_head.sh
331
348
  - fixtures/scripts/calculate-scores.sh
332
349
  - fixtures/scripts/print-helps.sh