Skip to content

Commit

Permalink
Merge branch 'master' into 16
Browse files Browse the repository at this point in the history
  • Loading branch information
Vatavuk committed Aug 8, 2018
2 parents 855d64d + 50f250c commit 345f962
Show file tree
Hide file tree
Showing 14 changed files with 441 additions and 98 deletions.
4 changes: 2 additions & 2 deletions src/main/java/io/zold/api/Network.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
* @since 0.1
*/
public interface Network extends Iterable<Remote> {

/**
* Push the wallet to the network. The network will select the
* remote node with the highest score (with a minimum of {@code 16}).
* Push the wallet to the network.
* @param wallet The wallet
*/
void push(Wallet wallet);
Expand Down
51 changes: 51 additions & 0 deletions src/main/java/io/zold/api/Remote.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@

package io.zold.api;

import org.cactoos.iterable.Repeated;
import org.cactoos.text.RandomText;

/**
* Remote node.
*
Expand All @@ -48,4 +51,52 @@ public interface Remote {
* @return The wallet
*/
Wallet pull(long id);

/**
* A Fake {@link Remote}.
*/
final class Fake implements Remote {

/**
* The remote's score.
*/
private final Score score;

/**
* Ctor.
* @param val The remote's score value
*/
public Fake(final int val) {
this(new RtScore(
new Repeated<>(val, new RandomText())
));
}

/**
* Ctor.
* @param score The remote's score
*/
public Fake(final Score score) {
this.score = score;
}

@Override
public Score score() {
return this.score;
}

@Override
public void push(final Wallet wallet) {
throw new UnsupportedOperationException(
"push() not yet supported"
);
}

@Override
public Wallet pull(final long id) {
throw new UnsupportedOperationException(
"pull() not yet supported"
);
}
}
}
4 changes: 0 additions & 4 deletions src/main/java/io/zold/api/RtNetwork.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@ public final class RtNetwork implements Network {
this.nodes = remotes;
}

// @todo #5:30min Implement scoring algorithm when paying taxes. Scoring
// algorithm must select the node with the highest score and with score
// >= 16. There are some tests for the scoring algorithm in NetworkTest:
// remove ignore tag from them after algorithm implementation.
@Override
public void push(final Wallet wallet) {
this.nodes.forEach(
Expand Down
31 changes: 23 additions & 8 deletions src/main/java/io/zold/api/RtTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ final class RtTransaction implements Transaction {
);

/**
* Pattern for amount String.
* Pattern for 16 symbol hex string.
*/
private static final Pattern AMT = Pattern.compile("[A-Fa-f0-9]{16}");
private static final Pattern HEX = Pattern.compile("[A-Fa-f0-9]{16}");

/**
* Pattern for parsing Signature.
Expand Down Expand Up @@ -138,7 +138,7 @@ public long amount() throws IOException {
)
).value()
).asString();
if (!RtTransaction.AMT.matcher(amnt).matches()) {
if (!RtTransaction.HEX.matcher(amnt).matches()) {
throw new IOException(
new UncheckedText(
new FormattedText(
Expand Down Expand Up @@ -183,12 +183,27 @@ public String prefix() throws IOException {
}
}

// @todo #15:30min Implement bnf() by parsing the string representation
// of transaction according to the pattern, described in the white
// paper. Replace relevant test case with actual tests.
@Override
public long bnf() {
throw new UnsupportedOperationException("bnf() not yet implemented");
public String bnf() throws IOException {
final String bnf =
new IoCheckedScalar<>(
() -> new ItemAt<>(
// @checkstyle MagicNumberCheck (1 line)
4, new SplitText(this.transaction, ";")
).value().asString()
).value();
if (!RtTransaction.HEX.matcher(bnf).matches()) {
throw new IOException(
new UncheckedText(
new FormattedText(
// @checkstyle LineLength (1 line)
"Invalid bnf string '%s', expecting hex string with 16 symbols",
bnf
)
).asString()
);
}
return bnf;
}

@Override
Expand Down
54 changes: 54 additions & 0 deletions src/main/java/io/zold/api/TaxBeneficiaries.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Yegor Bugayenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package io.zold.api;

import java.util.Comparator;
import org.cactoos.iterable.Filtered;
import org.cactoos.iterable.IterableEnvelope;
import org.cactoos.iterable.LengthOf;
import org.cactoos.iterable.Sorted;

/**
* {@link Remote} nodes that should receive taxes.
*
* @since 1.0
*/
public final class TaxBeneficiaries extends IterableEnvelope<Remote> {

/**
* Ctor.
*
* @param nodes Remote nodes to select from.
*/
public TaxBeneficiaries(final Iterable<Remote> nodes) {
super(() -> new Sorted<>(
Comparator.comparing(Remote::score),
new Filtered<>(
// @checkstyle MagicNumberCheck (1 line)
n -> new LengthOf(n.score().suffixes()).intValue() >= 16,
nodes
)
));
}
}
69 changes: 69 additions & 0 deletions src/main/java/io/zold/api/Taxes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Yegor Bugayenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package io.zold.api;

import org.cactoos.Proc;
import org.cactoos.text.FormattedText;
import org.cactoos.text.UncheckedText;

/**
* Taxes payment algorithm.
*
* @since 1.0
* @todo #40:30min Implement tax payment to remote nodes.
* Payment should happen only if the wallet is in debt of more than
* 1 Zold. Debt is difference between current taxes that should have
* been paid by wallet (see whitepaper for formula) and how much it
* already paid in the past. A first algorithm could pay the
* max to each node until there is nothing else to pay. The test
* must also be updated.
*/
public final class Taxes implements Proc<Wallet> {

/**
* The beneficiary nodes.
*/
private final Iterable<Remote> bnfs;

/**
* Ctor.
*
* @param nodes Remote nodes.
*/
public Taxes(final Iterable<Remote> nodes) {
this.bnfs = new TaxBeneficiaries(nodes);
}

@Override
public void exec(final Wallet wallet) {
throw new UnsupportedOperationException(
new UncheckedText(
new FormattedText(
"paying taxes to %s not yet supported",
this.bnfs
)
).asString()
);
}
}
3 changes: 2 additions & 1 deletion src/main/java/io/zold/api/Transaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ public interface Transaction {
/**
* Beneficiary.
* @return Beneficiary
* @throws IOException When something goes wrong
*/
long bnf();
String bnf() throws IOException;

/**
* Details.
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/io/zold/api/Wallets.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

package io.zold.api;

import java.io.IOException;

/**
* Wallets.
*
Expand All @@ -32,7 +34,8 @@
public interface Wallets extends Iterable<Wallet> {
/**
* Create a wallet.
* @return The new wallet
* @return The new wallet.
* @throws IOException If an error occurs.
*/
Wallet create();
Wallet create() throws IOException;
}
38 changes: 25 additions & 13 deletions src/main/java/io/zold/api/WalletsIn.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.Random;
import org.cactoos.Scalar;
import org.cactoos.func.IoCheckedFunc;
import org.cactoos.io.Directory;
import org.cactoos.iterable.Filtered;
import org.cactoos.iterable.Mapped;
import org.cactoos.scalar.IoCheckedScalar;
import org.cactoos.scalar.StickyScalar;
import org.cactoos.scalar.SyncScalar;
import org.cactoos.scalar.SolidScalar;
import org.cactoos.text.JoinedText;

/**
* Wallets in path.
Expand All @@ -54,6 +56,11 @@ public final class WalletsIn implements Wallets {
*/
private final IoCheckedFunc<Path, Boolean> filter;

/**
* Wallets file extension.
*/
private final String ext;

/**
* Ctor.
* @param pth Path with wallets
Expand All @@ -68,33 +75,38 @@ public WalletsIn(final Path pth) {
/**
* Ctor.
* @param pth Path with wallets
* @param ext File extension to match
* @param ext Wallets file extension
*/
public WalletsIn(final Scalar<Path> pth, final String ext) {
this.path = new IoCheckedScalar<>(
new SyncScalar<>(
new StickyScalar<>(pth)
)
new SolidScalar<>(pth)
);
this.filter = new IoCheckedFunc<Path, Boolean>(
(file) -> file.toFile().isFile()
&& FileSystems.getDefault()
.getPathMatcher(String.format("glob:**.%s", ext))
.matches(file)
);
this.ext = ext;
}

// @todo #4:30min Return the new instance of the Wallet, that will
// be created in the path with all wallets. Should be taken care of
// after Wallet interface will have implementations. Cover with tests and
// remove irrelevant test case.
// @todo #12:30min Create the new wallet in the path with all wallets.
// It should contain the correct content according to the
// white paper. Also add a the test to validate everything is ok.
@Override
public Wallet create() {
throw new UnsupportedOperationException("create() not yet supported");
public Wallet create() throws IOException {
final Path wpth = this.path.value().resolve(
new JoinedText(
".",
Long.toHexString(new Random().nextLong()),
this.ext
).asString()
);
Files.createFile(wpth);
return new Wallet.File(wpth);
}

@Override
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
public Iterator<Wallet> iterator() {
try {
return new Mapped<Path, Wallet>(
Expand Down
Loading

0 comments on commit 345f962

Please sign in to comment.