diff --git a/emulator/src/main/java/org/ton/java/emulator/TvmEmulator.java b/emulator/src/main/java/org/ton/java/emulator/TvmEmulator.java index a24d9b56..9a602d8b 100644 --- a/emulator/src/main/java/org/ton/java/emulator/TvmEmulator.java +++ b/emulator/src/main/java/org/ton/java/emulator/TvmEmulator.java @@ -78,7 +78,7 @@ public TvmEmulator build() { super.tvmEmulatorI = Native.load(super.pathToEmulatorSharedLib, TvmEmulatorI.class); if (isNull(super.verbosityLevel)) { - super.verbosityLevel = 2; + super.verbosityLevel = 3; } if (isNull(super.codeBoc)) { throw new Error("codeBoc is not set"); diff --git a/emulator/src/test/java/org/ton/java/emulator/TestTvmEmulator.java b/emulator/src/test/java/org/ton/java/emulator/TestTvmEmulator.java index 1baa256e..7fb1940a 100644 --- a/emulator/src/test/java/org/ton/java/emulator/TestTvmEmulator.java +++ b/emulator/src/test/java/org/ton/java/emulator/TestTvmEmulator.java @@ -16,6 +16,7 @@ import org.ton.java.cell.CellBuilder; import org.ton.java.cell.CellSlice; import org.ton.java.cell.TonHashMapE; +import org.ton.java.smartcontract.FuncCompiler; import org.ton.java.smartcontract.types.WalletV4R2Config; import org.ton.java.smartcontract.utils.MsgUtils; import org.ton.java.smartcontract.wallet.v4.WalletV4R2; @@ -25,9 +26,11 @@ import org.ton.java.tonlib.types.SmcLibraryResult; import org.ton.java.utils.Utils; +import java.io.IOException; import java.math.BigInteger; import java.time.Instant; import java.util.Collections; +import java.util.concurrent.ExecutionException; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; @@ -63,9 +66,9 @@ public static void setUpBeforeClass() { .pathToEmulatorSharedLib("G:/libs/emulator.dll") .codeBoc(code.toBase64()) .dataBoc(data.toBase64()) - .verbosityLevel(1) + .verbosityLevel(3) .build(); - tvmEmulator.setDebugEnabled(true); +// tvmEmulator.setDebugEnabled(true); } @Test @@ -225,6 +228,66 @@ public void testTvmEmulatorSendExternalMessage() { log.info("result sendExternalMessage: {}", result); } + @Test + public void testTvmEmulatorSendInternalMessageCustomContract() throws IOException, ExecutionException, InterruptedException { + FuncCompiler smcFunc = FuncCompiler.builder() + .contractPath("G:/smartcontracts/new-wallet-v4r2.fc") + .build(); + + String codeCellHex = smcFunc.compile(); + Cell codeCell = CellBuilder.beginCell().fromBoc(codeCellHex).endCell(); + + TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair(); + + Cell dataCell = CellBuilder.beginCell() + .storeUint(0, 32) // seqno + .storeUint(42, 32) // wallet id + .storeBytes(keyPair.getPublicKey()) + .storeUint(0, 1) //plugins dict empty + .endCell(); + + log.info("codeCellHex {}", codeCellHex); + log.info("dataCellHex {}", dataCell.toHex()); + + + tvmEmulator = TvmEmulator.builder() + .pathToEmulatorSharedLib("G:/libs/emulator.dll") + .codeBoc(codeCell.toBase64()) + .dataBoc(dataCell.toBase64()) + .verbosityLevel(1) + .build(); + + String address = contract.getAddress().toBounceable(); + String randSeedHex = Utils.sha256("ABC"); + Cell configAll = tonlib.getConfigAll(128); + + assertTrue(tvmEmulator.setLibs(getLibs().toBase64())); + +// assertTrue(tvmEmulator.setC7(address, +// Instant.now().getEpochSecond(), +// Utils.toNano(1).longValue(), +// randSeedHex +//// , null +// , configAll.toBase64() +// )); + +// tvmEmulator.setGasLimit(Utils.toNano(10).longValue()); + tvmEmulator.setDebugEnabled(true); + + Cell body = CellBuilder.beginCell() + .storeUint(0x706c7567, 32) // op request funds + .endCell(); + Message msg = MsgUtils.createInternalMessage( + Address.of("0:258e549638a6980ae5d3c76382afd3f4f32e34482dafc3751e3358589c8de00d") + , Utils.toNano(0.1), null, body, true); + + String resultBoc = tvmEmulator.sendInternalMessage(body.toBase64(), Utils.toNano(0.11).longValue()); + log.info("resultBoc {}", resultBoc); + SendExternalMessageResult result = gson.fromJson(resultBoc, SendExternalMessageResult.class); + log.info("result sendInternalMessage: {}", result); + + } + @Test public void testTvmEmulatorSendInternalMessage() { Cell body = CellBuilder.beginCell() diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/FuncCompiler.java b/smartcontract/src/main/java/org/ton/java/smartcontract/FuncCompiler.java index 24db06bc..4b67bb97 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/FuncCompiler.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/FuncCompiler.java @@ -14,7 +14,8 @@ import java.io.File; import java.io.IOException; import java.nio.charset.Charset; -import java.util.concurrent.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import static java.util.Objects.nonNull; @@ -137,6 +138,11 @@ public FuncCompiler build() { public String compile() throws IOException, ExecutionException, InterruptedException { String outputFiftAsmFile = executeFunc("-W", "dummy.boc", contractPath); + if (!outputFiftAsmFile.contains("2 boc+>B") + || outputFiftAsmFile.contains("cannot generate code") + || outputFiftAsmFile.contains("error: undefined function")) { + throw new Error("Compile error: " + outputFiftAsmFile); + } outputFiftAsmFile = StringUtils.replace(outputFiftAsmFile, "2 boc+>B", "0 boc+>B"); File file = new File(new File(contractPath).getParent() + "/dummy.fif"); @@ -149,9 +155,9 @@ public String compile() throws IOException, ExecutionException, InterruptedExcep } private String executeFunc(String... params) throws ExecutionException, InterruptedException { - Pair> result = execute(funcExecutable, params); + Pair result = execute(funcExecutable, params); - return result.getRight().get(); + return result.getRight(); } private String executeFift(String... params) { @@ -162,10 +168,10 @@ private String executeFift(String... params) { withInclude = new String[]{"-I", fiftAsmLibraryPath + ":" + fiftSmartcontLibraryPath}; } String[] all = ArrayUtils.addAll(withInclude, params); - Pair> result = execute(fiftExecutable, all); + Pair result = execute(fiftExecutable, all); if (nonNull(result)) { try { - return result.getRight().get(); + return result.getRight(); } catch (Exception e) { log.info("executeFift error " + e.getMessage()); return null; @@ -175,7 +181,7 @@ private String executeFift(String... params) { } } - private Pair> execute(String pathToBinary, String... command) { + private Pair execute(String pathToBinary, String... command) { String[] withBinaryCommand = new String[]{pathToBinary}; @@ -184,39 +190,33 @@ private Pair> execute(String pathToBinary, String... com try { log.info("execute: " + String.join(" ", withBinaryCommand)); - ExecutorService executorService = Executors.newSingleThreadExecutor(); - final ProcessBuilder pb = new ProcessBuilder(withBinaryCommand).redirectErrorStream(true); pb.directory(new File(new File(contractPath).getParent())); Process p = pb.start(); - Future future = executorService.submit(() -> { - - Thread.currentThread().setName(pathToBinary); - p.waitFor(1, TimeUnit.SECONDS); - - String resultInput = IOUtils.toString(p.getInputStream(), Charset.defaultCharset()); - - p.getInputStream().close(); - p.getErrorStream().close(); - p.getOutputStream().close(); - if (p.exitValue() == 2 || p.exitValue() == 0) { - return resultInput; - } else { - log.info("exit value " + p.exitValue()); - log.info(resultInput); - throw new Exception("Cannot compile smart-contract."); - } - }); + p.waitFor(1, TimeUnit.SECONDS); - executorService.shutdown(); + String resultInput = IOUtils.toString(p.getInputStream(), Charset.defaultCharset()); - return Pair.of(p, future); + p.getInputStream().close(); + p.getErrorStream().close(); + p.getOutputStream().close(); + if (p.exitValue() == 2 || p.exitValue() == 0) { + return Pair.of(p, resultInput); + } else { + log.info("exit value " + p.exitValue()); + log.info(resultInput); + throw new Exception("Cannot compile smart-contract."); + } } catch (final IOException e) { log.info(e.getMessage()); return null; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); } } diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestExampleContract.java b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestExampleContract.java index 884a1a28..e612fc4a 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestExampleContract.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/integrationtests/TestExampleContract.java @@ -23,7 +23,7 @@ public class TestExampleContract { @Test - public void testCustomContract() throws InterruptedException { + public void testExampleContract() throws InterruptedException { // echo "F182111193F30D79D517F2339A1BA7C25FDF6C52142F0F2C1D960A1F1D65E1E4" | xxd -r -p - > new-wallet.pk //byte[] secretKey = Utils.hexToBytes("F182111193F30D79D517F2339A1BA7C25FDF6C52142F0F2C1D960A1F1D65E1E4"); //TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPairFromSeed(secretKey); diff --git a/tonlib/src/test/java/org/ton/java/tonlib/TestTonlibJson.java b/tonlib/src/test/java/org/ton/java/tonlib/TestTonlibJson.java index f86a2120..9ed13f91 100644 --- a/tonlib/src/test/java/org/ton/java/tonlib/TestTonlibJson.java +++ b/tonlib/src/test/java/org/ton/java/tonlib/TestTonlibJson.java @@ -8,14 +8,15 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.ton.java.address.Address; import org.ton.java.cell.Cell; import org.ton.java.cell.CellBuilder; +import org.ton.java.cell.CellSlice; import org.ton.java.mnemonic.Mnemonic; +import org.ton.java.tlb.types.ConfigParams8; import org.ton.java.tonlib.types.*; import org.ton.java.utils.Utils; @@ -529,15 +530,18 @@ public void testTonlibRunMethodComputeReturnedStake() { log.info("return stake: {} ", Utils.formatNanoValue(returnStake.longValue())); } - @Ignore @Test public void testTonlibMyLocalTon() { Tonlib tonlib = Tonlib.builder() .verbosityLevel(VerbosityLevel.DEBUG) - .pathToGlobalConfig("G:\\Git_Projects\\MyLocalTon\\myLocalTon\\genesis\\db\\my-ton-global.config.json") + .pathToGlobalConfig("G:/Git_Projects/MyLocalTon/myLocalTon/genesis/db/my-ton-global.config.json") .ignoreCache(true) .build(); + BlockIdExt blockIdExt = tonlib.getMasterChainInfo().getLast(); + Cell cellConfig8 = tonlib.getConfigParam(blockIdExt, 8); + ConfigParams8 config8 = ConfigParams8.deserialize(CellSlice.beginParse(cellConfig8)); + log.info("config 8: {}", config8); RunResult seqno = tonlib.runMethod(Address.of("-1:CF624357217E2C9D2F4F5CA65F82FCBD16949FA00F46CA51358607BEF6D2CB53"), "seqno"); log.info("seqno RunResult {}", seqno); FullAccountState accountState1 = tonlib.getAccountState(Address.of("-1:85cda44e9838bf5a8c6d1de95c3e22b92884ae70ee1b550723a92a8ca0df3321"));