diff --git a/bitstring/src/main/java/org/ton/java/bitstring/BitString.java b/bitstring/src/main/java/org/ton/java/bitstring/BitString.java index 2f4f66a3..ded79496 100644 --- a/bitstring/src/main/java/org/ton/java/bitstring/BitString.java +++ b/bitstring/src/main/java/org/ton/java/bitstring/BitString.java @@ -40,7 +40,7 @@ public BitString(int[] bytes) { array = new ArrayDeque<>(0); initialLength = 0; } else { - byte[] bits = leftPadBytes(Utils.bytesToBitString(bytes).getBytes(), bytes.length * 8, '0'); + byte[] bits = Utils.leftPadBytes(Utils.bytesToBitString(bytes).getBytes(StandardCharsets.UTF_8), bytes.length * 8, '0'); array = new ArrayDeque<>(bits.length); for (byte bit : bits) { // whole length @@ -65,7 +65,7 @@ public BitString(byte[] bytes, int size) { array = new ArrayDeque<>(0); initialLength = 0; } else { - byte[] bits = leftPadBytes(Utils.bytesToBitString(bytes).getBytes(), bytes.length * 8, '0'); + byte[] bits = Utils.leftPadBytes(Utils.bytesToBitString(bytes).getBytes(StandardCharsets.UTF_8), bytes.length * 8, '0'); array = new ArrayDeque<>(bits.length); for (int i = 0; i < size; i++) { // specified length if (bits[i] == (byte) '1') { @@ -80,18 +80,6 @@ public BitString(byte[] bytes, int size) { } } - private byte[] leftPadBytes(byte[] bits, int sz, char c) { - if (sz <= bits.length) { - return bits; - } - - int diff = sz - bits.length; - byte[] b = new byte[diff + bits.length]; - Arrays.fill(b, 0, diff, (byte) c); - System.arraycopy(bits, 0, b, diff, bits.length); - - return b; - } /** * Create BitString limited by length @@ -212,7 +200,7 @@ public void writeUint(BigInteger number, int bitLength) { throw new Error("bitLength is too small for number, got number=" + number + ", bitLength=" + bitLength); } - byte[] s = number.toString(2).getBytes(); + byte[] s = number.toString(2).getBytes(StandardCharsets.UTF_8); if (s.length != bitLength) { s = repeatZerosAndMerge(bitLength - s.length, s); @@ -640,7 +628,7 @@ public byte[] toByteArray() { return new byte[0]; } - byte[] bin = getBitString().getBytes(); + byte[] bin = getBitString().getBytes(StandardCharsets.UTF_8); int sz = bin.length; byte[] result = new byte[(sz + 7) / 8]; @@ -660,7 +648,7 @@ public int[] toUintArray() { return new int[0]; } - byte[] bin = getBitString().getBytes(); + byte[] bin = getBitString().getBytes(StandardCharsets.UTF_8); int sz = bin.length; int[] result = new int[(sz + 7) / 8]; diff --git a/bitstring/src/main/java/org/ton/java/bitstring/RealBitString.java b/bitstring/src/main/java/org/ton/java/bitstring/RealBitString.java index 6a132c83..e3b6f17f 100644 --- a/bitstring/src/main/java/org/ton/java/bitstring/RealBitString.java +++ b/bitstring/src/main/java/org/ton/java/bitstring/RealBitString.java @@ -6,6 +6,7 @@ import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.logging.Logger; import static java.util.Objects.isNull; @@ -14,7 +15,7 @@ * Interestingly, but this solution loses to Deque array solution from memory footprint allocation. */ public class RealBitString { - + private static final Logger log = Logger.getLogger(RealBitString.class.getName()); byte[] array; public int writeCursor; public int readCursor; @@ -625,7 +626,7 @@ public void setTopUppedArray(byte[] arr, boolean fulfilledBytes) { // writeCursor = saveWriteCursor; if (!foundEndBit) { - System.err.println(Arrays.toString(arr) + ", " + fulfilledBytes); + log.info((Arrays.toString(arr) + ", " + fulfilledBytes)); throw new Error("Incorrect TopUppedArray"); } } diff --git a/cell/src/main/java/org/ton/java/cell/BinTree.java b/cell/src/main/java/org/ton/java/cell/BinTree.java index c233b7bd..4bfc5f45 100644 --- a/cell/src/main/java/org/ton/java/cell/BinTree.java +++ b/cell/src/main/java/org/ton/java/cell/BinTree.java @@ -18,22 +18,21 @@ public BinTree(Deque list) { } public Cell toCell() { - if (list.size() == 0) { + if (list.isEmpty()) { return CellBuilder.beginCell().endCell(); } return addToBinTree(list, null); } private static Cell addToBinTree(Deque cells, Cell left) { - CellBuilder c = CellBuilder.beginCell(); - if (cells.size() >= 1) { + if (!cells.isEmpty()) { CellBuilder cb = CellBuilder.beginCell(); cb.storeBit(true); cb.storeRef(CellBuilder.beginCell() .storeBit(false) .storeCell(isNull(left) ? cells.pop().toCell() : left) .endCell()); - if (cells.size() != 0) { + if (!cells.isEmpty()) { cb.storeRef(addToBinTree(cells, cells.pop().toCell())); } return cb.endCell(); diff --git a/cell/src/main/java/org/ton/java/cell/Cell.java b/cell/src/main/java/org/ton/java/cell/Cell.java index 824e0563..4a2a71ce 100644 --- a/cell/src/main/java/org/ton/java/cell/Cell.java +++ b/cell/src/main/java/org/ton/java/cell/Cell.java @@ -1,12 +1,12 @@ package org.ton.java.cell; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.ton.java.bitstring.BitString; import org.ton.java.tlb.types.Boc; import org.ton.java.utils.Utils; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; @@ -237,7 +237,7 @@ public void calculateHashes() { depth = refDepth; } } - if (refs.size() > 0) { + if (!refs.isEmpty()) { depth++; if (depth >= 1024) { throw new Error("depth is more than max depth (1023)"); @@ -359,9 +359,6 @@ public static Cell fromHex(String hexBitString) { BitString bss = new BitString(ba.length); bss.writeBitArray(ba); -// BitString f = new BitString(bss.getBitString().length()); -// f.writeBitString(bss); - return CellBuilder.beginCell().storeBitString(bss).endCell(); } catch (Exception e) { throw new Error("Cannot convert hex BitString to Cell. Error " + e.getMessage()); @@ -482,7 +479,7 @@ private static Boc deserializeBocHeader(byte[] data) { */ public String print(String indent) { StringBuilder s = new StringBuilder(indent + "x{" + bits.toHex() + "}\n"); - if (nonNull(refs) && refs.size() > 0) { + if (nonNull(refs) && !refs.isEmpty()) { for (Cell i : refs) { if (nonNull(i)) { s.append(i.print(indent + " ")); @@ -493,12 +490,11 @@ public String print(String indent) { } public String print() { - String indent = ""; - StringBuilder s = new StringBuilder(indent + "x{" + bits.toHex() + "}\n"); - if (nonNull(refs) && refs.size() > 0) { + StringBuilder s = new StringBuilder("x{" + bits.toHex() + "}\n"); + if (nonNull(refs) && !refs.isEmpty()) { for (Cell i : refs) { if (nonNull(i)) { - s.append(i.print(indent + " ")); + s.append(i.print(" ")); } } } @@ -509,7 +505,6 @@ public String print() { * Saves BoC to file */ public void toFile(String filename, boolean withCrc) { - byte[] boc = toBoc(withCrc); try { Files.write(Paths.get(filename), boc); @@ -595,7 +590,7 @@ public byte[] getRefsDescriptor(int lvl) { public byte[] getBitsDescriptor() { int bitsLength = bits.getLength(); - byte d3 = (byte) (Math.floor((double) bitsLength / 8) * 2); + byte d3 = (byte) ((bitsLength / 8) * 2); if ((bitsLength % 8) != 0) { d3++; } @@ -636,9 +631,7 @@ public byte[] toBoc(boolean withCRC, boolean withIdx, boolean withCacheBits, boo // taken from pytoniq - beautiful! private Map order(Map result) { - if (result.containsKey(this)) { - result.remove(this); - } + result.remove(this); result.put(this, null); for (Cell ref : this.refs) { ref.order(result); @@ -667,7 +660,7 @@ public byte[] toBoc(boolean hasCrc32c, boolean hasIdx, boolean hasCacheBits, boo } BigInteger cellsNum = BigInteger.valueOf(indexed.size()); - int cellsLen = (int) Math.floor((double) (cellsNum.bitLength() + 7) / 8); + int cellsLen = (cellsNum.bitLength() + 7) >> 3; byte[] payload = new byte[0]; List serializedCellLen = new ArrayList<>(); @@ -677,10 +670,9 @@ public byte[] toBoc(boolean hasCrc32c, boolean hasIdx, boolean hasCacheBits, boo serializedCellLen.add(BigInteger.valueOf(serializeResult.length)); } -// System.out.println(Utils.bytesToHex(payload)); // bytes needed to store len of payload - int sizeBits = Utils.log2(payload.length + 1); - int sizeBytes = (int) Math.ceil((double) sizeBits / 8); + int sizeBits = Utils.log2Ceil(payload.length + 1); + int sizeBytes = (sizeBits + 7) / 8; int numberOfRoots = 1; int absent = 0; @@ -707,14 +699,12 @@ public byte[] toBoc(boolean hasCrc32c, boolean hasIdx, boolean hasCacheBits, boo } private List flattenIndex(List src, boolean hasTopHash, boolean hasIntHashes) { - List pending = src; Map allCells = new HashMap<>(); Map notPermCells = new HashMap<>(); - Deque sorted = new ArrayDeque<>(); - while (pending.size() > 0) { + while (!pending.isEmpty()) { List cells = new ArrayList<>(pending); pending = new ArrayList<>(); @@ -731,7 +721,7 @@ private List flattenIndex(List src, boolean hasTopHash, boolean hasI } Map tempMark = new HashMap<>(); - while (notPermCells.size() > 0) { + while (!notPermCells.isEmpty()) { for (String key : notPermCells.keySet()) { visit(key, allCells, notPermCells, tempMark, sorted); break; @@ -739,7 +729,6 @@ private List flattenIndex(List src, boolean hasTopHash, boolean hasI } Map indexes = new HashMap<>(); - Deque tmpSorted = new ArrayDeque<>(sorted); int len = tmpSorted.size(); for (int i = 0; i < len; i++) { @@ -789,7 +778,6 @@ private void visit(String hash, Map allCells, Map no private byte[] serialize(int refIndexSzBytes) { byte[] body = Utils.unsignedBytesToSigned(CellSlice.beginParse(this).loadSlice(this.bits.getLength())); -// byte[] body1 = getDataBytes(); byte[] descriptors = getDescriptors(levelMask.getMask()); byte[] data = Utils.concatBytes(descriptors, body); @@ -825,12 +813,19 @@ private int getDepth(int lvlMask) { private byte[] getDataBytes() { if ((bits.getLength() % 8) > 0) { - String s = bits.toBitString(); - s = s + "1"; - if ((s.length() % 8) > 0) { - s = s + StringUtils.repeat("0", 8 - (s.length() % 8)); + byte[] a = bits.toBitString().getBytes(StandardCharsets.UTF_8); + int sz = a.length; + byte[] b = new byte[sz + 1]; + + System.arraycopy(a, 0, b, 0, sz); + b[sz] = (byte) '1'; + + int mod = b.length % 8; + if (mod > 0) { + b = Utils.rightPadBytes(b, b.length + (8 - mod), '0'); } - return Utils.bitStringToByteArray(s); + + return Utils.bitStringToByteArray(new String(b)); } else { return bits.toByteArray(); } @@ -851,9 +846,7 @@ public CellType getCellType() { switch (cellType) { case ORDINARY: { if (bits.getLength() >= 288) { - //int msk = clonedBits.readUint(8).intValue(); LevelMask msk = new LevelMask(clonedBits.readUint(8).intValue()); -// byte msk = levelMask; int lvl = msk.getLevel(); if ((lvl > 0) && (lvl <= 3) && (bits.getLength() >= 16 + (256 + 16) * msk.apply(lvl - 1).getHashIndex() + 1)) { return CellType.PRUNED_BRANCH; diff --git a/cell/src/main/java/org/ton/java/cell/CellBuilder.java b/cell/src/main/java/org/ton/java/cell/CellBuilder.java index a88bf798..2bc63a77 100644 --- a/cell/src/main/java/org/ton/java/cell/CellBuilder.java +++ b/cell/src/main/java/org/ton/java/cell/CellBuilder.java @@ -5,6 +5,7 @@ import org.ton.java.utils.Utils; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.util.List; import static java.util.Objects.isNull; @@ -219,7 +220,7 @@ public CellBuilder storeString(String str) { } public CellBuilder storeSnakeString(String str) { - byte[] strBytes = str.getBytes(); + byte[] strBytes = str.getBytes(StandardCharsets.UTF_8); Cell c = f(127 - 4, strBytes); return this.storeSlice(CellSlice.beginParse(c)); } diff --git a/cell/src/main/java/org/ton/java/cell/CellSlice.java b/cell/src/main/java/org/ton/java/cell/CellSlice.java index 9bb8ee5e..1e79e7bf 100644 --- a/cell/src/main/java/org/ton/java/cell/CellSlice.java +++ b/cell/src/main/java/org/ton/java/cell/CellSlice.java @@ -162,10 +162,10 @@ public TonHashMap loadDict(int n, Function keyParser, Functio TonHashMap x = new TonHashMap(n); x.deserialize(this, keyParser, valueParser); - if (refs.size() != 0) { + if (!refs.isEmpty()) { refs.remove(0); } - if (refs.size() != 0) { + if (!refs.isEmpty()) { refs.remove(0); } @@ -179,10 +179,10 @@ public TonHashMapAug loadDictAug(int n, Function keyParser, F TonHashMapAug x = new TonHashMapAug(n); x.deserialize(this, keyParser, valueParser, extraParser); - if (refs.size() != 0) { + if (!refs.isEmpty()) { refs.remove(0); } - if (refs.size() != 0) { + if (!refs.isEmpty()) { refs.remove(0); } @@ -439,7 +439,7 @@ public String loadString(int length) { * @return String */ public String loadSnakeString() { - List result = new ArrayList<>(); + StringBuilder s = new StringBuilder(); checkBitsOverflow(bits.getLength()); // bitsLeft CellSlice ref = this.clone(); @@ -447,12 +447,10 @@ public String loadSnakeString() { try { BitString bitString = ref.loadBits(ref.bits.getLength()); - int[] uintArray = bitString.toUintArray(); - List resultList = new ArrayList<>(uintArray.length); - for (int value : uintArray) { - resultList.add(value); + byte[] uintArray = bitString.toByteArray(); + for (byte value : uintArray) { + s.append((char) value); } - result.addAll(resultList); if (ref.refs.size() > 1) { throw new Error("more than one ref, it is not snake string"); @@ -468,7 +466,7 @@ public String loadSnakeString() { ref = null; } - return result.stream().map(m -> new String(new byte[]{m.byteValue()})).collect(Collectors.joining()); + return s.toString(); } public BitString loadBits(int length) { diff --git a/cell/src/main/java/org/ton/java/cell/LevelMask.java b/cell/src/main/java/org/ton/java/cell/LevelMask.java index e97f5808..6f1ea2da 100644 --- a/cell/src/main/java/org/ton/java/cell/LevelMask.java +++ b/cell/src/main/java/org/ton/java/cell/LevelMask.java @@ -39,7 +39,7 @@ public static int calculateMinimumBits(int number) { return 0; } - return (int) Math.ceil(Math.log(number + 1) / Math.log(2)); + return Integer.SIZE - Integer.numberOfLeadingZeros(number); } public static int calculateOnesBits(int number) { diff --git a/cell/src/main/java/org/ton/java/tlb/types/BlockCreateStats.java b/cell/src/main/java/org/ton/java/tlb/types/BlockCreateStats.java index f1be32a6..82d45046 100644 --- a/cell/src/main/java/org/ton/java/tlb/types/BlockCreateStats.java +++ b/cell/src/main/java/org/ton/java/tlb/types/BlockCreateStats.java @@ -10,9 +10,9 @@ public interface BlockCreateStats { - public Cell toCell(); + Cell toCell(); - public static BlockCreateStats deserialize(CellSlice cs) { + static BlockCreateStats deserialize(CellSlice cs) { long magic = cs.loadUint(8).longValue(); if (magic == 0x17) { return BlockCreateStatsOrdinary.deserialize(cs); diff --git a/cell/src/main/java/org/ton/java/tlb/types/BlockIdExtShardIdent.java b/cell/src/main/java/org/ton/java/tlb/types/BlockIdExtShardIdent.java index f0e40beb..b565b9ad 100644 --- a/cell/src/main/java/org/ton/java/tlb/types/BlockIdExtShardIdent.java +++ b/cell/src/main/java/org/ton/java/tlb/types/BlockIdExtShardIdent.java @@ -51,12 +51,11 @@ public Cell toCell() { } public static BlockIdExtShardIdent deserialize(CellSlice cs) { - BlockIdExtShardIdent blockIdExtShardIdent = BlockIdExtShardIdent.builder() + return BlockIdExtShardIdent.builder() .shardId(ShardIdent.deserialize(cs)) .seqno(cs.loadUint(32).longValue()) .rootHash(cs.loadUint(256)) .fileHash(cs.loadUint(256)) .build(); - return blockIdExtShardIdent; } } diff --git a/cell/src/main/java/org/ton/java/tlb/types/ComputePhaseVM.java b/cell/src/main/java/org/ton/java/tlb/types/ComputePhaseVM.java index cccb1cbf..cc959c69 100644 --- a/cell/src/main/java/org/ton/java/tlb/types/ComputePhaseVM.java +++ b/cell/src/main/java/org/ton/java/tlb/types/ComputePhaseVM.java @@ -43,7 +43,7 @@ public Cell toCell() { .storeBit(msgStateUsed) .storeBit(accountActivated) .storeCoins(gasFees) - .storeSlice(CellSlice.beginParse(((ComputePhaseVMDetails) details).toCell())) + .storeSlice(CellSlice.beginParse(details.toCell())) .endCell(); } diff --git a/cell/src/main/java/org/ton/java/tlb/types/CreditPhase.java b/cell/src/main/java/org/ton/java/tlb/types/CreditPhase.java index 34cef087..8e553301 100644 --- a/cell/src/main/java/org/ton/java/tlb/types/CreditPhase.java +++ b/cell/src/main/java/org/ton/java/tlb/types/CreditPhase.java @@ -26,7 +26,7 @@ public class CreditPhase { public Cell toCell() { return CellBuilder.beginCell() .storeCoinsMaybe(dueFeesCollected) - .storeSlice(CellSlice.beginParse(((CurrencyCollection) credit).toCell())) + .storeSlice(CellSlice.beginParse(credit.toCell())) .endCell(); } diff --git a/cell/src/main/java/org/ton/java/tlb/types/DepthBalanceInfo.java b/cell/src/main/java/org/ton/java/tlb/types/DepthBalanceInfo.java index af927787..b2384f03 100644 --- a/cell/src/main/java/org/ton/java/tlb/types/DepthBalanceInfo.java +++ b/cell/src/main/java/org/ton/java/tlb/types/DepthBalanceInfo.java @@ -7,8 +7,8 @@ import org.ton.java.cell.Cell; import org.ton.java.cell.CellBuilder; import org.ton.java.cell.CellSlice; +import org.ton.java.utils.Utils; -import static org.ton.java.utils.Utils.log2; @Builder @Getter @@ -23,7 +23,7 @@ public class DepthBalanceInfo { public Cell toCell() { return CellBuilder.beginCell() - .storeUint(depth, (int) Math.ceil(log2((depth)))) + .storeUint(depth, Utils.log2Ceil(depth)) .storeCell(currencies.toCell()).endCell(); } diff --git a/cell/src/main/java/org/ton/java/tlb/types/StoragePhase.java b/cell/src/main/java/org/ton/java/tlb/types/StoragePhase.java index 6bff0d01..d6f448e2 100644 --- a/cell/src/main/java/org/ton/java/tlb/types/StoragePhase.java +++ b/cell/src/main/java/org/ton/java/tlb/types/StoragePhase.java @@ -29,7 +29,7 @@ public Cell toCell() { return CellBuilder.beginCell() .storeCoins(storageFeesCollected) .storeCoinsMaybe(storageFeesDue) - .storeSlice(CellSlice.beginParse(((AccStatusChange) statusChange).toCell())) + .storeSlice(CellSlice.beginParse(statusChange.toCell())) .endCell(); } diff --git a/cell/src/main/java/org/ton/java/tlb/types/Text.java b/cell/src/main/java/org/ton/java/tlb/types/Text.java index 5c8bef69..eb1bd75e 100644 --- a/cell/src/main/java/org/ton/java/tlb/types/Text.java +++ b/cell/src/main/java/org/ton/java/tlb/types/Text.java @@ -28,7 +28,7 @@ public class Text { private int chunksNum = 1; public Cell toCell() { - if (value.length() == 0) { + if (value.isEmpty()) { return CellBuilder.beginCell().storeUint(0, 8).endCell(); } if (maxFirstChunkSize > MaxTextChunkSize) { diff --git a/cell/src/main/java/org/ton/java/tlb/types/TransactionDescription.java b/cell/src/main/java/org/ton/java/tlb/types/TransactionDescription.java index 1ac55c60..c17a5420 100644 --- a/cell/src/main/java/org/ton/java/tlb/types/TransactionDescription.java +++ b/cell/src/main/java/org/ton/java/tlb/types/TransactionDescription.java @@ -24,9 +24,6 @@ public Cell toCell() { } else if (description instanceof TransactionDescriptionOrdinary) { c.storeUint(0b000, 3); c.storeSlice(CellSlice.beginParse(((TransactionDescriptionOrdinary) description).toCell())); - } else if (description instanceof TransactionDescriptionOrdinary) { - c.storeUint(0b000, 3); - c.storeSlice(CellSlice.beginParse(((TransactionDescriptionOrdinary) description).toCell())); } return c.endCell(); } diff --git a/cell/src/main/java/org/ton/java/tlb/types/VmStackList.java b/cell/src/main/java/org/ton/java/tlb/types/VmStackList.java index 0f8c7b33..762515e0 100644 --- a/cell/src/main/java/org/ton/java/tlb/types/VmStackList.java +++ b/cell/src/main/java/org/ton/java/tlb/types/VmStackList.java @@ -30,7 +30,6 @@ public class VmStackList { public Cell toCell() { Cell list = CellBuilder.beginCell().endCell(); - int i = 0; for (VmStackValue value : tos) { Cell valueCell = value.toCell(); list = CellBuilder.beginCell() diff --git a/cell/src/main/java/org/ton/java/tlb/types/VmTuple.java b/cell/src/main/java/org/ton/java/tlb/types/VmTuple.java index 2c5109f5..af221644 100644 --- a/cell/src/main/java/org/ton/java/tlb/types/VmTuple.java +++ b/cell/src/main/java/org/ton/java/tlb/types/VmTuple.java @@ -24,7 +24,7 @@ public class VmTuple { public Cell toCell() { List pValues = new ArrayList<>(values); - if (pValues.size() == 0) { + if (pValues.isEmpty()) { return CellBuilder.beginCell().endCell(); } @@ -39,7 +39,7 @@ public Cell toCell() { public static Cell toCell(List pValues) { List lValues = new ArrayList<>(pValues); - if (lValues.size() == 0) { + if (lValues.isEmpty()) { return CellBuilder.beginCell().endCell(); } diff --git a/cell/src/main/java/org/ton/java/tlb/types/VmTupleRef.java b/cell/src/main/java/org/ton/java/tlb/types/VmTupleRef.java index f62443a8..fb50ddd7 100644 --- a/cell/src/main/java/org/ton/java/tlb/types/VmTupleRef.java +++ b/cell/src/main/java/org/ton/java/tlb/types/VmTupleRef.java @@ -35,7 +35,7 @@ public Cell toCell(int len) { } if (len == 1) { return CellBuilder.beginCell() - .storeRef(((VmStackValue) values.get(0)).toCell()) + .storeRef(values.get(0).toCell()) .endCell(); } return CellBuilder.beginCell() @@ -44,12 +44,12 @@ public Cell toCell(int len) { } public static Cell toCell(List pValues) { - if (pValues.size() == 0) { + if (pValues.isEmpty()) { return CellBuilder.beginCell().endCell(); } if (pValues.size() == 1) { return CellBuilder.beginCell() - .storeRef(((VmStackValue) pValues.get(0)).toCell()) + .storeRef(pValues.get(0).toCell()) .endCell(); } return CellBuilder.beginCell() diff --git a/emulator/src/main/java/org/ton/java/emulator/TxEmulator.java b/emulator/src/main/java/org/ton/java/emulator/TxEmulator.java index a25f9383..98699603 100644 --- a/emulator/src/main/java/org/ton/java/emulator/TxEmulator.java +++ b/emulator/src/main/java/org/ton/java/emulator/TxEmulator.java @@ -88,11 +88,11 @@ public TxEmulator build() { throw new Error("Can't create tx emulator instance"); } - System.out.printf("Java TON Tx Emulator configuration:\n" + + log.info(String.format("Java TON Tx Emulator configuration:\n" + "Location: %s\n" + "Verbosity level: %s", super.pathToEmulatorSharedLib, - super.verbosityLevel); + super.verbosityLevel)); return super.build(); } } diff --git a/liteclient/src/main/java/org/ton/java/liteclient/LiteClient.java b/liteclient/src/main/java/org/ton/java/liteclient/LiteClient.java index 0d38978f..29fe2a43 100644 --- a/liteclient/src/main/java/org/ton/java/liteclient/LiteClient.java +++ b/liteclient/src/main/java/org/ton/java/liteclient/LiteClient.java @@ -17,6 +17,7 @@ import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -53,10 +54,6 @@ public class LiteClient { */ private boolean testnet; -// private LiteClient() { -// -// } - public static class LiteClientBuilder { } @@ -122,13 +119,13 @@ public LiteClient build() { } } - System.out.printf("Java Lite-Client configuration:\n" + + log.info(String.format("Java Lite-Client configuration:\n" + "Location: %s\n" + "Path to global config: %s\n" + "Testnet: %s%n", super.pathToLiteClientBinary, super.pathToGlobalConfig, - super.testnet); + super.testnet)); } catch (Exception e) { throw new RuntimeException("Error creating lite-client instance: " + e.getMessage()); @@ -482,7 +479,7 @@ public Pair> execute(String... command) { return resultInput; } catch (IOException e) { - e.printStackTrace(); + log.info(e.getMessage()); return null; } }); diff --git a/liteclient/src/main/java/org/ton/java/liteclient/LiteClientParser.java b/liteclient/src/main/java/org/ton/java/liteclient/LiteClientParser.java index eaf7d3bf..6339c814 100644 --- a/liteclient/src/main/java/org/ton/java/liteclient/LiteClientParser.java +++ b/liteclient/src/main/java/org/ton/java/liteclient/LiteClientParser.java @@ -13,6 +13,7 @@ import java.math.BigDecimal; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; @@ -49,19 +50,19 @@ public static ResultLastBlock parseLast(String stdout) { return null; } - if (StringUtils.contains(stdout, "adnl query timeout")) { + if (StringUtils.indexOf(stdout, "adnl query timeout") != -1) { log.info("Blockchain node is not ready"); return null; } - if (StringUtils.contains(stdout, "server appears to be out of sync")) { + if (StringUtils.indexOf(stdout, "server appears to be out of sync") != -1) { log.info("Blockchain node is out of sync"); } try { String last = stdout.replace(EOL, SPACE); - Long craetedAt = Long.parseLong(sb(last, "created at ", OPEN).trim()); + Long createdAt = Long.parseLong(sb(last, "created at ", OPEN).trim()); String fullBlockSeqno = sb(last, "last masterchain block is ", SPACE).trim(); String shortBlockSeqno = OPEN + sb(fullBlockSeqno, OPEN, CLOSE) + CLOSE; String rootHashId = sb(fullBlockSeqno, ":", ":"); @@ -71,12 +72,12 @@ public static ResultLastBlock parseLast(String stdout) { Long wc = Long.parseLong(sb(shortBlockSeqno, OPEN, ",")); Long secondsAgo = -1L; if (last.contains("seconds ago")) { - String craetedAtStr = sb(last, "created at ", "seconds ago"); - secondsAgo = Long.parseLong(sb(craetedAtStr, OPEN, SPACE).trim()); + String createdAtStr = sb(last, "created at ", "seconds ago"); + secondsAgo = Long.parseLong(sb(createdAtStr, OPEN, SPACE).trim()); } return ResultLastBlock.builder() - .createdAt(craetedAt) + .createdAt(createdAt) .seqno(pureBlockSeqno) .rootHash(rootHashId) .fileHash(fileHashId) @@ -101,7 +102,6 @@ public static ResultLastBlock parseCreateHardFork(String stdout) { try { String last = stdout.replace(EOL, SPACE); - String fullBlockSeqno = last.substring(last.indexOf("saved to disk") + 13).trim(); String shortBlockSeqno = OPEN + sb(fullBlockSeqno, OPEN, CLOSE) + CLOSE; String rootHashId = sb(fullBlockSeqno, ":", ":"); @@ -620,11 +620,11 @@ private static List parseTxs(String content, Boolean includeMessage List txs = new ArrayList<>(); List txsList = LiteClientParser.findStringBlocks(content, "transaction:("); if (!txsList.isEmpty()) { - txs = txsList.stream().map(x -> LiteClientParser.parseTransaction(x, includeMessageBody)).collect(Collectors.toList()); - return txs; - } else { - return txs; + txs = txsList.stream() + .map(x -> LiteClientParser.parseTransaction(x, includeMessageBody)) + .collect(Collectors.toList()); } + return txs; } private static OutMsgDescr parseOutMsgDescr(String outMsgDescr, Boolean includeMessageBody) { @@ -754,23 +754,25 @@ private static Body parseBody(String bodyContent) { .build(); } String[] bodyCells = bodyContent.split("x\\{"); - ArrayList cells = new ArrayList<>(Arrays.asList(bodyCells)); - ArrayList cleanedCells = cleanCells(cells); + List cells = new ArrayList<>(Arrays.asList(bodyCells)); + List cleanedCells = cleanCells(cells); return Body.builder() .cells(cleanedCells) .build(); } - private static ArrayList cleanCells(ArrayList cells) { - ArrayList cleanCells = new ArrayList<>(); - if (!isNull(cells) && cells.size() > 0) { - cells.remove(0); - cells.stream().filter(s -> s.replace(")", "").replace(" ", "").replace("}", "").length() > 0).forEach(s -> { - cleanCells.add(s.replace(")", "").replace(" ", "").replace("}", "")); - }); + private static List cleanCells(List cells) { + if (cells == null || cells.isEmpty()) { + return new ArrayList<>(); } - return cleanCells; + + cells.remove(0); + + return cells.stream() + .map(s -> s.replaceAll("[)} ]", "")) + .filter(s -> !s.isEmpty()) + .collect(Collectors.toList()); } private static Init parseInit(String initContent) { @@ -783,15 +785,15 @@ private static Init parseInit(String initContent) { } String code = sbb(initContent, "code:("); String[] codeCells = isNull(code) ? new String[0] : code.split("x\\{"); - ArrayList cleanedCodeCells = cleanCells(new ArrayList<>(Arrays.asList(codeCells))); + List cleanedCodeCells = cleanCells(new ArrayList<>(Arrays.asList(codeCells))); String data = sbb(initContent, "data:("); String[] dataCells = isNull(data) ? new String[0] : data.split("x\\{"); - ArrayList cleanedDataCells = cleanCells(new ArrayList<>(Arrays.asList(dataCells))); + List cleanedDataCells = cleanCells(new ArrayList<>(Arrays.asList(dataCells))); String library = sbb(initContent, "library:("); String[] libraryCells = isNull(library) ? new String[0] : library.split("x\\{"); - ArrayList cleanedLibraryCells = cleanCells(new ArrayList<>(Arrays.asList(libraryCells))); + List cleanedLibraryCells = cleanCells(new ArrayList<>(Arrays.asList(libraryCells))); return Init.builder() .code(cleanedCodeCells) @@ -911,11 +913,9 @@ private static Transaction parseTransaction(String str, Boolean includeMessageBo origStatus = convertAccountStatus(origStatus); endStatus = convertAccountStatus(endStatus); - //String inMsgField = sb(transaction, "in_msg:", "))))") + ")))"; // small hack String inMsgField = sbb(transaction, "in_msg:"); // small hack Message inMsg = parseInMessage(inMsgField, includeMessageBody); - //String outMsgsField = sb(transaction, "out_msgs:", "))))))") + ")))"; // small hack String outMsgsField = sbb(transaction, "out_msgs:"); List outMsgs = parseOutMessages(outMsgsField, includeMessageBody); @@ -1163,7 +1163,7 @@ private static Value readValue(String str) { List otherCurrencies = new ArrayList<>(); - if (nonNull(str) && str.contains("node:(hmn_fork")) { + if (str.contains("node:(hmn_fork")) { // exist extra currencies List currenciesLeft = findStringBlocks(str, "left:(hm_edge"); List currenciesRight = findStringBlocks(str, "right:(hm_edge"); @@ -1175,7 +1175,7 @@ private static Value readValue(String str) { for (String cur : currencies) { Byte len = parseByteSpace(cur, "len:"); String label = sb(cur, "s:", CLOSE); - if (!StringUtils.isEmpty(label)) { + if (StringUtils.isNotEmpty(label)) { label = label.substring(1); } if (!isNull(len)) { @@ -1214,9 +1214,8 @@ private static List readLibraries(String str) { if (!libraries.isEmpty()) { for (String lib : libraries) { - //Byte len = parseByteSpace(cur, "len:"); String label = sb(lib, "s:", CLOSE); - if (!StringUtils.isEmpty(label)) { + if (StringUtils.isNotEmpty(label)) { label = label.substring(1); } String type = sb(lib, "value:(", SPACE); @@ -1224,7 +1223,7 @@ private static List readLibraries(String str) { String raw = sbb(lib, "root:("); String[] rawCells = isNull(raw) ? new String[0] : raw.split("x\\{"); - ArrayList rawLibrary = cleanCells(new ArrayList<>(Arrays.asList(rawCells))); + List rawLibrary = cleanCells(new ArrayList<>(Arrays.asList(rawCells))); Library library = Library.builder() .label(label) @@ -1300,9 +1299,6 @@ private static Info parseBlockInfo(String blockInf) { .build(); } - public static String sb(String str, String from, String to) { - return StringUtils.substringBetween(str, from, to); - } private static BigDecimal parseBigDecimalSpace(String str, String from) { try { @@ -1390,101 +1386,6 @@ private static Byte parseByteBracket(String str, String from) { return isNull(result) ? null : Byte.parseByte(result); } - /** - * Finds matching closing bracket in string starting with pattern - */ - public static int findPosOfClosingBracket(String str, String pattern) { - int i; - int openBracketIndex = pattern.indexOf(OPEN); - int index = str.indexOf(pattern) + openBracketIndex; - - ArrayDeque st = new ArrayDeque<>(); - - for (i = index; i < str.length(); i++) { - if (str.charAt(i) == '(') { - st.push((int) str.charAt(i)); - } else if (str.charAt(i) == ')') { - if (st.isEmpty()) { - return i; - } - st.pop(); - if (st.isEmpty()) { - return i; - } - } - } - return -1; - } - - /** - * Finds single string-block starting with pattern and ending with CLOSE - */ - public static String sbb(String str, String pattern) { - if (isNull(str) || !str.contains(pattern)) - return null; - - int openindex = str.indexOf(pattern) + pattern.indexOf(OPEN); - int closeIndex = LiteClientParser.findPosOfClosingBracket(str, pattern); - if (closeIndex == -1) { - return null; - } - return str.substring(openindex, closeIndex + 1).trim(); - } - - /** - * Finds multiple string-blocks starting with pattern and ending with CLOSE - */ - public static List findStringBlocks(String str, String pattern) { - List result = new ArrayList<>(); - - if (isNull(str) || !str.contains(pattern)) - return result; - - int fromIndex = 0; - int foundIndex = str.indexOf(pattern, fromIndex); - - while (foundIndex != -1) { - foundIndex += pattern.indexOf(OPEN); - String foundPattern = sbb(str.substring(fromIndex), pattern); - if (nonNull(foundPattern)) { - result.add(foundPattern); - fromIndex = foundIndex + foundPattern.length(); - foundIndex = str.indexOf(pattern, fromIndex); - } else { - foundIndex = -1; - } - } - return result; - } - - /** - * copy of the method findStringBlocks() but additionally prepends result with label value - */ - public static List findLeafsWithLabel(String str, String pattern) { - List result = new ArrayList<>(); - - if (isNull(str) || !str.contains(pattern)) - return result; - - int fromIndex = 0; - int foundIndex = str.indexOf(pattern, fromIndex); - - while (foundIndex != -1) { - foundIndex += pattern.indexOf(OPEN); - String foundPattern = sbb(str.substring(fromIndex), pattern); - if (nonNull(foundPattern)) { - result.add(str.substring(foundIndex - 150, foundIndex) + foundPattern); - fromIndex = foundIndex + foundPattern.length(); - foundIndex = str.indexOf(pattern, fromIndex); - } else { - foundIndex = -1; - } - } - - return result; - } - - public static LiteClientAccountState parseGetAccount(String stdout) { if (isNull(stdout)) { @@ -1538,11 +1439,11 @@ public static LiteClientAccountState parseGetAccount(String stdout) { String code = sbb(state, "code:("); String[] codeCells = isNull(code) ? new String[0] : code.split("x\\{"); - ArrayList stateAccountCode = cleanCells(new ArrayList<>(Arrays.asList(codeCells))); + List stateAccountCode = cleanCells(new ArrayList<>(Arrays.asList(codeCells))); String data = sbb(state, "data:("); String[] dataCells = isNull(data) ? new String[0] : data.split("x\\{"); - ArrayList stateAccountData = cleanCells(new ArrayList<>(Arrays.asList(dataCells))); + List stateAccountData = cleanCells(new ArrayList<>(Arrays.asList(dataCells))); String stateAccountLibrary = sbb(state, "library:("); List libraries = readLibraries(stateAccountLibrary); @@ -1577,7 +1478,7 @@ public static LiteClientAccountState parseGetAccount(String stdout) { public static long parseRunMethodSeqno(String stdout) { try { - return Long.parseLong(StringUtils.substringBetween(stdout, "result: [", "]").trim()); + return Long.parseLong(sb(stdout, "result: [", "]").trim()); } catch (Exception e) { return -1L; } @@ -1592,7 +1493,7 @@ public static List parseRunMethodParticipantList(String return Collections.emptyList(); } - String result = StringUtils.substringBetween(stdout, "result: [ (", ") ]"); + String result = sb(stdout, "result: [ (", ") ]"); result = result.replace("] [", ","); result = result.replace("[", ""); @@ -1600,7 +1501,7 @@ public static List parseRunMethodParticipantList(String String[] participants = result.split(","); List participantsList = new ArrayList<>(); - if (result.length() == 0) { + if (result.isEmpty()) { return participantsList; } for (String participant : participants) { @@ -1625,10 +1526,191 @@ public static ResultComputeReturnStake parseRunMethodComputeReturnStake(String s .build(); } - String result = StringUtils.substringBetween(stdout, "result: [", "]"); + String result = sb(stdout, "result: [", "]"); return ResultComputeReturnStake.builder() .stake(new BigDecimal(result.trim())) .build(); } + + private static String sb(String str, String from, String to) { + if (str == null || from == null || to == null) { + return null; + } + + byte[] bytes = str.getBytes(StandardCharsets.UTF_8); + byte[] fromBytes = from.getBytes(StandardCharsets.UTF_8); + byte[] toBytes = to.getBytes(StandardCharsets.UTF_8); + + int startIndex = indexOf(bytes, fromBytes, 0); + if (startIndex == -1) { + return null; + } + startIndex += fromBytes.length; + + int endIndex = indexOf(bytes, toBytes, startIndex); + if (endIndex == -1) { + return null; + } + + byte[] resultBytes = Arrays.copyOfRange(bytes, startIndex, endIndex); + return new String(resultBytes, StandardCharsets.UTF_8); + } + + /** + * Finds single string-block starting with pattern and ending with CLOSE + */ + private static String sbb(String str, String pattern) { + if (str == null || pattern == null || !str.contains(pattern)) { + return null; + } + + byte[] strBytes = str.getBytes(StandardCharsets.UTF_8); + byte[] patternBytes = pattern.getBytes(StandardCharsets.UTF_8); + + int patternIndex = indexOf(strBytes, patternBytes, 0); + int patternOpenIndex = indexOf(patternBytes, OPEN.getBytes(StandardCharsets.UTF_8), 0); + if (patternIndex == -1) { + return null; + } + + int openIndex = patternIndex + patternOpenIndex; + int closeIndex = findPosOfClosingBracket(strBytes, patternIndex); + + if (closeIndex == -1) { + return null; + } + + return new String(strBytes, openIndex, closeIndex - openIndex + 1, StandardCharsets.UTF_8).trim(); + } + + /** + * Finds matching closing bracket in string starting with pattern + */ + private static int findPosOfClosingBracket(byte[] strBytes, int patternIndex) { + Deque stack = new ArrayDeque<>(); + + for (int i = patternIndex; i < strBytes.length; i++) { + if (strBytes[i] == (byte) '(') { + stack.push(i); + } else if (strBytes[i] == (byte) ')') { + if (stack.isEmpty()) { + return i; + } + stack.pop(); + if (stack.isEmpty()) { + return i; + } + } + } + return -1; + } + + /** + * Finds multiple string-blocks starting with pattern and ending with CLOSE + */ + private static List findStringBlocks(String str, String pattern) { + List result = new ArrayList<>(); + + if (isNull(str) || !str.contains(pattern)) + return result; + + byte[] strBytes = str.getBytes(StandardCharsets.UTF_8); + byte[] patternBytes = pattern.getBytes(StandardCharsets.UTF_8); + + int fromIndex = 0; + int patternIndex = indexOf(strBytes, patternBytes, fromIndex); + + while (patternIndex != -1) { + byte[] tmp = Arrays.copyOfRange(strBytes, patternIndex, patternIndex + patternBytes.length); + int openCharIndex = indexOf(tmp, OPEN.getBytes(StandardCharsets.UTF_8), 0); + int openIndex = patternIndex + openCharIndex; + if (openIndex == -1) { + break; + } + int closeIndex = findPosOfClosingBracket(strBytes, patternIndex); + + if (closeIndex != -1) { + result.add(new String(Arrays.copyOfRange(strBytes, openIndex, closeIndex + 1))); + fromIndex = closeIndex + 1; + patternIndex = indexOf(strBytes, patternBytes, fromIndex); + } else { + break; + } + } + return result; + } + + /** + * copy of the method findStringBlocks() but additionally prepends result with label value + */ + private static List findLeafsWithLabel(String str, String pattern) { + List result = new ArrayList<>(); + + if (isNull(str) || !str.contains(pattern)) + return result; + + byte[] strBytes = str.getBytes(StandardCharsets.UTF_8); + byte[] patternBytes = pattern.getBytes(StandardCharsets.UTF_8); + + + int fromIndex = 0; + final int dataToAddLen = 150; + int patternIndex = indexOf(strBytes, patternBytes, fromIndex); + + while (patternIndex != -1) { + byte[] tmp = Arrays.copyOfRange(strBytes, patternIndex, patternIndex + pattern.length()); + int openCharIndex = indexOf(tmp, OPEN.getBytes(StandardCharsets.UTF_8), 0); + int openIndex = patternIndex + openCharIndex; + + if (openIndex == -1) { + break; + } + int closeIndex = findPosOfClosingBracket(strBytes, patternIndex); + + if (closeIndex != -1) { + int start = Math.max(patternIndex - dataToAddLen, 0); + byte[] beforePattern = Arrays.copyOfRange(strBytes, start, patternIndex); + byte[] foundPattern = Arrays.copyOfRange(strBytes, patternIndex, closeIndex + 1); + + result.add(new String(beforePattern) + new String(foundPattern)); + fromIndex = closeIndex + 1; + patternIndex = indexOf(strBytes, patternBytes, fromIndex); + } else { + break; + } + } + return result; + } + + private static int indexOf(byte[] array, byte[] target, int fromIndex) { + if (target.length == 0) { + return fromIndex; + } + if (target.length > array.length) { + return -1; + } + + int[] a = new int[256]; + for (int i = 0; i < target.length; i++) { + a[target[i] & 0xFF] = i; + } + + int m = target.length; + int n = array.length; + + int s = fromIndex; + while (s <= n - m) { + int j = m - 1; + while (j >= 0 && target[j] == array[s + j]) { + j--; + } + if (j < 0) { + return s; + } else { + s += Math.max(1, j - a[array[s + j] & 0xFF]); + } + } + return -1; + } } diff --git a/mnemonic/src/main/java/org/ton/java/mnemonic/Ed25519.java b/mnemonic/src/main/java/org/ton/java/mnemonic/Ed25519.java index c224bda0..7769072a 100644 --- a/mnemonic/src/main/java/org/ton/java/mnemonic/Ed25519.java +++ b/mnemonic/src/main/java/org/ton/java/mnemonic/Ed25519.java @@ -16,7 +16,6 @@ public static byte[] privateKey() throws NoSuchAlgorithmException { } public static byte[] publicKey(byte[] privateKey) throws NoSuchAlgorithmException { - SecureRandom rnd = SecureRandom.getInstanceStrong(); byte[] publicKey = new byte[KEY_SIZE]; org.bouncycastle.math.ec.rfc8032.Ed25519.generatePublicKey(privateKey, 0, publicKey, 0); return publicKey; diff --git a/mnemonic/src/main/java/org/ton/java/mnemonic/Mnemonic.java b/mnemonic/src/main/java/org/ton/java/mnemonic/Mnemonic.java index 720ea801..4d8bc18d 100644 --- a/mnemonic/src/main/java/org/ton/java/mnemonic/Mnemonic.java +++ b/mnemonic/src/main/java/org/ton/java/mnemonic/Mnemonic.java @@ -116,9 +116,7 @@ public static List generate(int wordCount) throws NoSuchAlgorithmExcepti public static List generate(int wordCount, String password) throws NoSuchAlgorithmException, InvalidKeyException { List mnemonic; SecureRandom rnd = SecureRandom.getInstanceStrong(); - long c = 0; while (true) { - c++; mnemonic = new ArrayList<>(); for (int i = 0; i < wordCount; i++) { mnemonic.add(DEFAULT_WORDLIST[rnd.nextInt(DEFAULT_WORDLIST.length)]); diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/Executor.java b/smartcontract/src/main/java/org/ton/java/smartcontract/Executor.java index 07d407f0..96353a45 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/Executor.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/Executor.java @@ -46,6 +46,7 @@ public static Pair execute(String pathToBinary, String workDir, log.info(e.getMessage()); return null; } catch (Exception e) { + log.info(e.getMessage()); throw new RuntimeException(e); } } diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/FiftRunner.java b/smartcontract/src/main/java/org/ton/java/smartcontract/FiftRunner.java index 5914be9c..7e700cd5 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/FiftRunner.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/FiftRunner.java @@ -38,7 +38,7 @@ private static class CustomFiftRunnerBuilder extends FiftRunnerBuilder { @Override public FiftRunner build() { if (StringUtils.isEmpty(super.fiftExecutablePath)) { - System.out.println("checking if fift is installed..."); + log.info("checking if fift is installed..."); String errorMsg = "Make sure you have fift and func installed. See https://github.com/ton-blockchain/packages for instructions."; try { ProcessBuilder pb = new ProcessBuilder("fift", "-h").redirectErrorStream(true); @@ -48,13 +48,13 @@ public FiftRunner build() { throw new Error("Cannot execute simple fift command.\n" + errorMsg); } fiftAbsolutePath = detectAbsolutePath(); - System.out.println("fift found at " + fiftAbsolutePath); + log.info("fift found at " + fiftAbsolutePath); super.fiftExecutable = "fift"; } catch (Exception e) { throw new Error("Cannot execute simple fift command.\n" + errorMsg); } } else { - System.out.println("using " + super.fiftExecutablePath); + log.info("using " + super.fiftExecutablePath); super.fiftExecutable = super.fiftExecutablePath; } @@ -86,7 +86,7 @@ public FiftRunner build() { } } } - System.out.println("using include dirs: " + super.fiftAsmLibraryPath + ", " + super.fiftSmartcontLibraryPath); + log.info("using include dirs: " + super.fiftAsmLibraryPath + ", " + super.fiftSmartcontLibraryPath); return super.build(); } @@ -136,7 +136,7 @@ private static String detectAbsolutePath() { } return null; } catch (Exception e) { - throw new Error("Cannot detect absolute path to executable " + "fift"); + throw new Error("Cannot detect absolute path to executable fift " + e.getMessage()); } } } diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/FuncRunner.java b/smartcontract/src/main/java/org/ton/java/smartcontract/FuncRunner.java index e1ab20a5..87c2edb7 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/FuncRunner.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/FuncRunner.java @@ -33,7 +33,7 @@ private static class CustomFuncRunnerBuilder extends FuncRunnerBuilder { @Override public FuncRunner build() { if (StringUtils.isEmpty(super.funcExecutablePath)) { - System.out.println("checking if func is installed..."); + log.info("checking if func is installed..."); String errorMsg = "Make sure you have fift and func installed. See https://github.com/ton-blockchain/packages for instructions."; try { @@ -45,15 +45,15 @@ public FuncRunner build() { } String funcAbsolutePath = detectAbsolutePath(); - System.out.println("func found at " + funcAbsolutePath); + log.info("func found at " + funcAbsolutePath); super.funcExecutable = "func"; } catch (Exception e) { - e.printStackTrace(); + log.info(e.getMessage()); throw new Error("Cannot execute simple func command.\n" + errorMsg); } } else { - System.out.println("using " + super.funcExecutablePath); + log.info("using " + super.funcExecutablePath); super.funcExecutable = super.funcExecutablePath; } return super.build(); @@ -63,7 +63,11 @@ public FuncRunner build() { public String run(String workdir, String... params) { Pair result = Executor.execute(funcExecutable, workdir, params); - return result.getRight(); + if (result != null && result.getRight() != null) { + return result.getRight(); + } + + return ""; } private static String detectAbsolutePath() { @@ -89,7 +93,7 @@ private static String detectAbsolutePath() { } return null; } catch (Exception e) { - throw new Error("Cannot detect absolute path to executable func"); + throw new Error("Cannot detect absolute path to executable func " + e.getMessage()); } } } diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/SmartContractCompiler.java b/smartcontract/src/main/java/org/ton/java/smartcontract/SmartContractCompiler.java index 2afba2d2..6e1e2382 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/SmartContractCompiler.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/SmartContractCompiler.java @@ -53,7 +53,7 @@ public SmartContractCompiler build() { * @return code of BoC in hex */ public String compile() throws IOException { - System.out.println("workdir " + new File(contractPath).getParent()); + log.info("workdir " + new File(contractPath).getParent()); String outputFiftAsmFile = funcRunner.run(new File(contractPath).getParent(), "-W", "dummy.boc", contractPath); diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/dns/DnsUtils.java b/smartcontract/src/main/java/org/ton/java/smartcontract/dns/DnsUtils.java index 92f76a68..e1b10057 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/dns/DnsUtils.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/dns/DnsUtils.java @@ -29,7 +29,7 @@ public class DnsUtils { * @return BigInteger */ static BigInteger categoryToInt(String category) { - if ((isNull(category)) || (category.length() == 0)) { + if ((isNull(category)) || (category.isEmpty())) { return BigInteger.ZERO; } diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/lockup/LockupWalletV1.java b/smartcontract/src/main/java/org/ton/java/smartcontract/lockup/LockupWalletV1.java index 754d0ff0..fd00ec8c 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/lockup/LockupWalletV1.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/lockup/LockupWalletV1.java @@ -167,7 +167,7 @@ public Cell createDataCell() { ); cell.storeDict(cellDict); - cell.storeCoins(isNull(lockupConfig.getTotalLockedalue()) ? BigInteger.ZERO : lockupConfig.getTotalLockedalue()); + cell.storeCoins(isNull(lockupConfig.getTotalLockedValue()) ? BigInteger.ZERO : lockupConfig.getTotalLockedValue()); cell.storeBit(false); // empty locked dict cell.storeCoins(isNull(lockupConfig.getTotalRestrictedValue()) ? BigInteger.ZERO : lockupConfig.getTotalRestrictedValue()); cell.storeBit(false); // empty restricted dict diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/multisig/MultiSigWallet.java b/smartcontract/src/main/java/org/ton/java/smartcontract/multisig/MultiSigWallet.java index c8514433..7cef4760 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/multisig/MultiSigWallet.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/multisig/MultiSigWallet.java @@ -3,6 +3,7 @@ import com.iwebpp.crypto.TweetNaclFast; import lombok.Builder; import lombok.Getter; +import lombok.extern.java.Log; import org.apache.commons.lang3.tuple.Pair; import org.ton.java.address.Address; import org.ton.java.cell.*; @@ -21,6 +22,7 @@ @Builder @Getter +@Log public class MultiSigWallet implements Contract { //https://github.com/akifoq/multisig/blob/master/multisig-code.fc @@ -138,7 +140,6 @@ public List getPublicKeys() { for (Map.Entry entry : loadedDict.elements.entrySet()) { CellSlice cSlice = CellSlice.beginParse((Cell) entry.getValue()); BigInteger pubKey = cSlice.loadUint(256); - long flood = cSlice.loadUint(8).longValue(); publicKeys.add(pubKey); } return publicKeys; @@ -446,7 +447,7 @@ private static void checkIfSignatureExists(Cell order, byte[] signature) { Cell ref = cs.loadRef(); while (nonNull(ref)) { byte[] sig = CellSlice.beginParse(ref).loadBytes(512); - System.out.println("sig " + Utils.bytesToHex(signature)); + log.info("sig " + Utils.bytesToHex(signature)); if (sig == signature) { throw new Error("Your signature is already presented"); } @@ -468,7 +469,7 @@ public static Cell addSignature1(Cell order, int pubkeyIndex, TweetNaclFast.Sign byte[] signature = signCell(keyPair, o.endCell()); - System.out.println("sig " + Utils.bytesToHex(signature)); + log.info("sig " + Utils.bytesToHex(signature)); // checkIfSignatureExists(order, signature); diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/token/ft/JettonMinter.java b/smartcontract/src/main/java/org/ton/java/smartcontract/token/ft/JettonMinter.java index 495bf5fc..15cc5e86 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/token/ft/JettonMinter.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/token/ft/JettonMinter.java @@ -3,6 +3,7 @@ import com.iwebpp.crypto.TweetNaclFast; import lombok.Builder; import lombok.Getter; +import lombok.extern.java.Log; import org.apache.commons.lang3.StringUtils; import org.ton.java.address.Address; import org.ton.java.cell.Cell; @@ -27,6 +28,7 @@ @Builder @Getter +@Log public class JettonMinter implements Contract { TweetNaclFast.Signature.KeyPair keyPair; Address adminAddress; @@ -95,7 +97,7 @@ public Cell createDataCell() { @Override public Cell createCodeCell() { if (StringUtils.isNotEmpty(code)) { - System.out.println("Using custom JettonMinter"); + log.info("Using custom JettonMinter"); return CellBuilder.beginCell(). fromBoc(code). endCell(); @@ -195,7 +197,7 @@ public JettonMinterData getJettonData(Tonlib tonlib) { String jettonContentUri = null; try { jettonContentUri = NftUtils.parseOffChainUriCell(jettonContentCell); - } catch (Exception e) { + } catch (Error e) { //todo } diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/token/ft/JettonMinterStableCoin.java b/smartcontract/src/main/java/org/ton/java/smartcontract/token/ft/JettonMinterStableCoin.java index 755e820e..e9255b65 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/token/ft/JettonMinterStableCoin.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/token/ft/JettonMinterStableCoin.java @@ -3,6 +3,7 @@ import com.iwebpp.crypto.TweetNaclFast; import lombok.Builder; import lombok.Getter; +import lombok.extern.java.Log; import org.apache.commons.lang3.StringUtils; import org.ton.java.address.Address; import org.ton.java.cell.Cell; @@ -27,6 +28,7 @@ @Builder @Getter +@Log public class JettonMinterStableCoin implements Contract { TweetNaclFast.Signature.KeyPair keyPair; Address adminAddress; @@ -77,7 +79,7 @@ public String getName() { @Override public Cell createDataCell() { if (StringUtils.isNotEmpty(code)) { - System.out.println("Using custom JettonMinter"); + log.info("Using custom JettonMinter"); return CellBuilder.beginCell() .storeCoins(BigInteger.ZERO) .storeAddress(adminAddress) @@ -101,7 +103,7 @@ public Cell createDataCell() { @Override public Cell createCodeCell() { if (StringUtils.isNotEmpty(code)) { - System.out.println("Using custom JettonMinter"); + log.info("Using custom JettonMinter"); return CellBuilder.beginCell(). fromBoc(code). endCell(); diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/token/nft/NftUtils.java b/smartcontract/src/main/java/org/ton/java/smartcontract/token/nft/NftUtils.java index 8abe1d10..0af9d20d 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/token/nft/NftUtils.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/token/nft/NftUtils.java @@ -1,5 +1,6 @@ package org.ton.java.smartcontract.token.nft; +import lombok.extern.java.Log; import org.apache.commons.lang3.StringUtils; import org.ton.java.address.Address; import org.ton.java.cell.Cell; @@ -19,6 +20,7 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +@Log public class NftUtils { @@ -47,7 +49,7 @@ static String parseUri(String uri) { try { return URLDecoder.decode(uri, String.valueOf(StandardCharsets.UTF_8)); } catch (UnsupportedEncodingException e) { - System.out.println(e.getMessage()); + log.info(e.getMessage()); return null; } } diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/types/AdnlAddress.java b/smartcontract/src/main/java/org/ton/java/smartcontract/types/AdnlAddress.java index 7d4a7430..8b385469 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/types/AdnlAddress.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/types/AdnlAddress.java @@ -26,7 +26,7 @@ public AdnlAddress(AdnlAddress anyForm) { } public AdnlAddress(String anyForm) { - if ((isNull(anyForm)) || (anyForm.length() == 0)) { + if ((isNull(anyForm)) || (anyForm.isEmpty())) { throw new Error("Invalid address"); } if ((anyForm.length() != 64)) { diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/types/LockupConfig.java b/smartcontract/src/main/java/org/ton/java/smartcontract/types/LockupConfig.java index 768f206d..1b518546 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/types/LockupConfig.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/types/LockupConfig.java @@ -23,5 +23,5 @@ public class LockupConfig { public List allowedDestinations; public BigInteger totalRestrictedValue; - public BigInteger totalLockedalue; + public BigInteger totalLockedValue; } diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/wallet/ContractUtils.java b/smartcontract/src/main/java/org/ton/java/smartcontract/wallet/ContractUtils.java index fd54f329..ec759da9 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/wallet/ContractUtils.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/wallet/ContractUtils.java @@ -1,6 +1,7 @@ package org.ton.java.smartcontract.wallet; +import lombok.extern.java.Log; import org.apache.commons.lang3.StringUtils; import org.ton.java.address.Address; import org.ton.java.smartcontract.token.ft.JettonMinter; @@ -10,6 +11,7 @@ import java.math.BigInteger; +@Log public class ContractUtils { public static long getSeqno(Tonlib tonlib, Address address) { @@ -21,7 +23,7 @@ public static boolean isDeployed(Tonlib tonlib, Address address) { } public static void waitForDeployment(Tonlib tonlib, Address address, int timeoutSeconds) { - System.out.println("waiting for deployment up to " + timeoutSeconds + " sec"); + log.info("waiting for deployment up to " + timeoutSeconds + " sec"); int i = 0; do { if (++i * 2 >= timeoutSeconds) { @@ -33,7 +35,7 @@ public static void waitForDeployment(Tonlib tonlib, Address address, int timeout } public static void waitForBalanceChange(Tonlib tonlib, Address address, int timeoutSeconds) { - System.out.println("waiting for balance change up to " + timeoutSeconds + " sec"); + log.info("waiting for balance change up to " + timeoutSeconds + " sec"); BigInteger initialBalance = tonlib.getAccountBalance(address); int i = 0; do { @@ -46,7 +48,7 @@ public static void waitForBalanceChange(Tonlib tonlib, Address address, int time } public static void waitForJettonBalanceChange(Tonlib tonlib, Address jettonMinter, Address address, int timeoutSeconds) { - System.out.println("waiting for jetton balance change up to " + timeoutSeconds + " sec"); + log.info("waiting for jetton balance change up to " + timeoutSeconds + " sec"); BigInteger initialBalance = getJettonBalance(tonlib, jettonMinter, address); int i = 0; do { @@ -69,7 +71,7 @@ public static BigInteger getJettonBalance(Tonlib tonlib, Address jettonMinter, A JettonWallet jettonWallet = jettonMinterWallet.getJettonWallet(destinationAddress); return jettonWallet.getBalance(); - } catch (Exception e) { + } catch (Error e) { return new BigInteger("-1"); } } diff --git a/tl/src/main/java/org/ton/java/tl/types/Text.java b/tl/src/main/java/org/ton/java/tl/types/Text.java index ff5a3032..bf27b26d 100644 --- a/tl/src/main/java/org/ton/java/tl/types/Text.java +++ b/tl/src/main/java/org/ton/java/tl/types/Text.java @@ -28,7 +28,7 @@ public class Text { private int chunksNum = 1; public Cell toCell() { - if (value.length() == 0) { + if (value.isEmpty()) { return CellBuilder.beginCell().storeUint(0, 8).endCell(); } if (maxFirstChunkSize > MaxTextChunkSize) { diff --git a/tonlib/src/main/java/org/ton/java/tonlib/Tonlib.java b/tonlib/src/main/java/org/ton/java/tonlib/Tonlib.java index 6d22c89d..46f637bb 100644 --- a/tonlib/src/main/java/org/ton/java/tonlib/Tonlib.java +++ b/tonlib/src/main/java/org/ton/java/tonlib/Tonlib.java @@ -238,7 +238,7 @@ public Tonlib build() { super.tonlibJson = Native.load(super.pathToTonlibSharedLib, TonlibJsonI.class); super.tonlib = super.tonlibJson.tonlib_client_json_create(); - System.out.printf("Java Tonlib configuration:\n" + + log.info(String.format("Java Tonlib configuration:\n" + "Location: %s\n" + "Verbosity level: %s (%s)\n" + "Keystore in memory: %s\n" + @@ -268,7 +268,7 @@ public Tonlib build() { super.ignoreCache, super.testnet, super.receiveTimeout, - super.receiveRetryTimes); + super.receiveRetryTimes)); // set verbosity VerbosityLevelQuery verbosityLevelQuery = VerbosityLevelQuery.builder().new_verbosity_level(super.verbosityLevel.ordinal()).build(); @@ -278,7 +278,7 @@ public Tonlib build() { initTonlibConfig(globalConfigCurrent); if (super.usingAllLiteServers) { - System.out.println("Using lite-server at index: " + (super.liteServerIndex) + " (" + Utils.int2ip(globalConfigCurrent.getLiteservers()[0].getIp()) + ")"); + log.info("Using lite-server at index: " + (super.liteServerIndex) + " (" + Utils.int2ip(globalConfigCurrent.getLiteservers()[0].getIp()) + ")"); } } catch (Exception e) { @@ -368,7 +368,7 @@ private String receive() { int retry = 0; while (isNull(result)) { if (retry > 0) { - System.out.println("retry " + retry); + log.info("retry " + retry); } if (++retry > receiveRetryTimes) { throw new Error("Error in tonlib.receive(), " + receiveRetryTimes + " times was not able retrieve result from lite-server."); @@ -399,7 +399,7 @@ private String syncAndRead(String query) { // } if (response.contains("error")) { - System.out.println(response); + log.info(response); if (++retry > receiveRetryTimes) { // System.out.println("Last response: " + response); @@ -415,7 +415,7 @@ private String syncAndRead(String query) { newLiteServers[0] = liteServers[retry % originalGlobalConfigInternal.getLiteservers().length]; globalConfigCurrent.setLiteservers(newLiteServers); - System.out.println("Trying next lite-server at index: " + (retry % originalGlobalConfigInternal.getLiteservers().length) + " (" + Utils.int2ip(globalConfigCurrent.getLiteservers()[0].getIp()) + ")"); + log.info("Trying next lite-server at index: " + (retry % originalGlobalConfigInternal.getLiteservers().length) + " (" + Utils.int2ip(globalConfigCurrent.getLiteservers()[0].getIp()) + ")"); reinitTonlibConfig(globalConfigCurrent); //repeat request @@ -443,7 +443,7 @@ private String syncAndRead(String query) { if (sync.getSync_state().getTo_seqno() != 0) { pct = (sync.getSync_state().getCurrent_seqno() * 100) / (double) sync.getSync_state().getTo_seqno(); } - System.out.println("Synchronized: " + String.format("%.2f%%", pct)); + log.info("Synchronized: " + String.format("%.2f%%", pct)); } if (isNull(response)) { throw new RuntimeException("Error in waitForSyncDone(), response is null."); @@ -455,7 +455,7 @@ private String syncAndRead(String query) { response = receive(); } if (response.contains("error")) { - System.out.println(response); + log.info(response); if (++retry > receiveRetryTimes) { throw new Error("Error in tonlib.receive(), " + receiveRetryTimes + " times was not able retrieve result from lite-server."); @@ -805,7 +805,7 @@ public RawAccountState getRawAccountState(Address address, BlockIdExt blockId) { if (StringUtils.isEmpty(blockId.getRoot_hash())) { throw new Error("Cannot lookup block for hashes by seqno. Probably block not in db. Try to specify block's root and file hashes manually in base64 format."); } - System.out.println("got hashes "+blockId); + log.info("got hashes " + blockId); } AccountAddressOnly accountAddressOnly = AccountAddressOnly.builder() @@ -909,7 +909,7 @@ public FullAccountState getAccountState(Address address, BlockIdExt blockId) { if (StringUtils.isEmpty(blockId.getRoot_hash())) { throw new Error("Cannot lookup block for hashes by seqno. Probably block not in db. Try to specify block's root and file hashes manually in base64 format."); } - System.out.println("got hashes "+blockId); + log.info("got hashes " + blockId); } AccountAddressOnly accountAddressOnly = AccountAddressOnly.builder() diff --git a/utils/src/main/java/org/ton/java/utils/Utils.java b/utils/src/main/java/org/ton/java/utils/Utils.java index 34157dcd..142bb0c4 100644 --- a/utils/src/main/java/org/ton/java/utils/Utils.java +++ b/utils/src/main/java/org/ton/java/utils/Utils.java @@ -17,13 +17,16 @@ import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; +import java.util.Arrays; import java.util.Base64; import java.util.Locale; import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.stream.Collectors; public class Utils { + private static final Logger log = Logger.getLogger(Utils.class.getName()); private static final String HEXES = "0123456789ABCDEF"; private static final long BLN1 = 1000000000L; private static final BigInteger BI_BLN1 = BigInteger.valueOf(BLN1); @@ -519,8 +522,8 @@ public static byte[] dynamicIntBytes(BigInteger val, int sz) { return result; } - public static int log2(int val) { - return (int) Math.ceil(Math.log(val) / Math.log(2)); + public static int log2Ceil(int val) { + return Integer.SIZE - Integer.numberOfLeadingZeros(val - 1); } @@ -782,16 +785,16 @@ public static void sleep(long seconds) { try { TimeUnit.SECONDS.sleep(seconds); } catch (Throwable e) { - System.out.println(e.getMessage()); + log.info(e.getMessage()); } } public static void sleep(long seconds, String text) { try { - System.out.println("pause " + seconds + " seconds, " + text); + log.info(String.format("pause %s seconds, %s", seconds, text)); TimeUnit.SECONDS.sleep(seconds); } catch (Throwable e) { - System.out.println(e.getMessage()); + log.info(e.getMessage()); } } @@ -867,4 +870,29 @@ private static void checkToncoinsOverflow(BigInteger amount) { public static String generateString(int length, String character) { return RandomStringUtils.random(length, character); } + + public static byte[] leftPadBytes(byte[] bits, int sz, char c) { + if (sz <= bits.length) { + return bits; + } + + int diff = sz - bits.length; + byte[] b = new byte[sz]; + Arrays.fill(b, 0, diff, (byte) c); + System.arraycopy(bits, 0, b, diff, bits.length); + + return b; + } + + public static byte[] rightPadBytes(byte[] bits, int sz, char c) { + if (sz <= bits.length) { + return bits; + } + + byte[] b = new byte[sz]; + System.arraycopy(bits, 0, b, 0, bits.length); + Arrays.fill(b, bits.length, sz, (byte) c); + + return b; + } }