Skip to content

Commit

Permalink
add windows stdout handling from shared lib;
Browse files Browse the repository at this point in the history
adjust info msgs when executing from Blockchain
  • Loading branch information
neodix42 committed Nov 8, 2024
1 parent 6f6b6ed commit 634625b
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 25 deletions.
16 changes: 13 additions & 3 deletions blockchain/src/main/java/org/ton/java/Blockchain.java
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ private void printBlockchainInfo() {
if (super.network == Network.EMULATOR) {

System.out.printf(
"Java Blockchain configuration:\n"
"Blockchain configuration:\n"
+ "Target network: %s\n"
+ "Emulator location: %s, configType: %s, txVerbosity: %s, tvmVerbosity: %s\n"
+ "Emulator ShardAccount: balance %s, address: %s, lastPaid: %s, lastTransLt: %s\n"
Expand Down Expand Up @@ -241,7 +241,7 @@ private void printBlockchainInfo() {
: super.customContractPath);
} else {
System.out.printf(
"\nBlockchain configuration:\n"
"Blockchain configuration:\n"
+ "Target network: %s\n"
+ "Emulator not used\n"
+ "Tonlib location: %s\n"
Expand Down Expand Up @@ -380,7 +380,16 @@ public boolean deploy(int waitForDeploymentSeconds) {
public GetterResult runGetMethod(String methodName) {
System.out.printf("running GetMethod %s on %s\n", methodName, network);
if (network == Network.EMULATOR) {
return GetterResult.builder().emulatorResult(tvmEmulator.runGetMethod(methodName)).build();
GetterResult result =
GetterResult.builder().emulatorResult(tvmEmulator.runGetMethod(methodName)).build();
if (result.getEmulatorResult().getVm_exit_code() != 0) {
throw new Error(
"Cannot execute run method ("
+ methodName
+ "), Error:\n"
+ result.getEmulatorResult().getVm_log());
}
return result;
} else {
Address address;
if (nonNull(contract)) {
Expand All @@ -396,6 +405,7 @@ public BigInteger runGetSeqNo() {
System.out.printf("running %s on %s\n", "seqno", network);
if (network == Network.EMULATOR) {
return tvmEmulator.runGetSeqNo();

} else {
Address address;
if (nonNull(contract)) {
Expand Down
48 changes: 47 additions & 1 deletion blockchain/src/test/java/org/ton/java/BlockchainTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
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.smartcontract.faucet.TestnetFaucet;
import org.ton.java.smartcontract.types.WalletV3Config;
import org.ton.java.smartcontract.utils.MsgUtils;
import org.ton.java.smartcontract.wallet.v3.WalletV3R2;
import org.ton.java.smartcontract.wallet.v5.WalletV5;
import org.ton.java.tlb.types.Message;
Expand All @@ -19,6 +21,8 @@
@Slf4j
@RunWith(JUnit4.class)
public class BlockchainTest {
Address dummyAddress = Address.of("EQAyjRKDnEpTBNfRHqYdnzGEQjdY4KG3gxgqiG3DpDY46u8G");

@Test
public void testDeployV3R2ContractOnEmulator() {
TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair();
Expand Down Expand Up @@ -247,6 +251,8 @@ public void testSendMessageV3R2ContractOnEmulator() {
Blockchain blockchain = Blockchain.builder().network(Network.EMULATOR).contract(wallet).build();
assertThat(blockchain.deploy(30)).isTrue();

blockchain.runGetMethod("seqno");

WalletV3Config configA =
WalletV3Config.builder()
.walletId(42)
Expand All @@ -259,7 +265,17 @@ public void testSendMessageV3R2ContractOnEmulator() {

Message msg = wallet.prepareExternalMsg(configA);

blockchain.sendExternal(msg);
SendExternalResult result = blockchain.sendExternal(msg);
log.info("result {}", result);
}

@Test(expected = Error.class)
public void testSendMessageV3R2ContractOnEmulatorErrorNoMethod() {
TweetNaclFast.Signature.KeyPair keyPair = Utils.generateSignatureKeyPair();
WalletV3R2 wallet = WalletV3R2.builder().keyPair(keyPair).walletId(42).build();
Blockchain blockchain = Blockchain.builder().network(Network.EMULATOR).contract(wallet).build();
assertThat(blockchain.deploy(30)).isTrue();
blockchain.runGetMethod("unique");
}

@Test
Expand All @@ -279,4 +295,34 @@ public void testSendMessageCustomContractOnTestnetTolk() {
System.out.printf("result %s\n", result);
System.out.printf("returned seqno %s\n", blockchain.runGetSeqNo());
}

@Test
public void testSendMessageCustomContractOnEmulatorTolk() {
Blockchain blockchain =
Blockchain.builder()
.network(Network.EMULATOR)
.customContractAsResource("simple.tolk")
.customContractDataCell(
CellBuilder.beginCell()
.storeUint(0, 32)
.storeInt(Utils.getRandomInt(), 32)
.endCell())
// .tvmEmulatorVerbosityLevel(TvmVerbosityLevel.WITH_ALL_STACK_VALUES)
// .txEmulatorVerbosityLevel(TxVerbosityLevel.WITH_ALL_STACK_VALUES)
.build();
assertThat(blockchain.deploy(30)).isTrue();
blockchain.runGetMethod("unique");
System.out.printf("returned seqno %s\n", blockchain.runGetSeqNo());

Cell bodyCell =
CellBuilder.beginCell()
.storeUint(0, 32) // seqno
.endCell();

Message extMsg = MsgUtils.createExternalMessage(dummyAddress, null, bodyCell);

SendExternalResult result = blockchain.sendExternal(extMsg);
// log.info("result {}", result);

}
}
8 changes: 4 additions & 4 deletions blockchain/src/test/resources/simple.fc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "stdlib.fc";

() recv_internal(int my_ton_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure inline {
~dump(40);
~dump(140);
~dump(my_ton_balance);

slice cs = in_msg_full.begin_parse();
Expand All @@ -16,7 +16,7 @@
}

() recv_external(slice in_msg_body) impure inline {
~dump(41);
~dump(141);

var msg_seqno = in_msg_body~load_uint(32);
var ds = get_data().begin_parse();
Expand All @@ -31,11 +31,11 @@
}

int seqno() method_id {
~dump(42);
~dump(142);
return get_data().begin_parse().preload_uint(32);
}

int unique() method_id {
~dump(42);
~dump(143);
return get_data().begin_parse().skip_bits(32).preload_uint(32);
}
8 changes: 4 additions & 4 deletions blockchain/src/test/resources/simple.tolk
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "@stdlib/gas-payments"

@inline
fun onInternalMessage(myTonBalance: int, msgValue: int, inMsgFull: cell, inMsgBody: slice) {
debugPrint(40);
debugPrint(140);
debugPrint(myTonBalance);

var cs: slice = inMsgFull.beginParse();
Expand All @@ -18,7 +18,7 @@ fun onInternalMessage(myTonBalance: int, msgValue: int, inMsgFull: cell, inMsgBo

@inline
fun onExternalMessage(inMsgBody: slice) {
debugPrint(41);
debugPrint(141);

var msgSeqno = inMsgBody.loadUint(32);
var ds = getContractData().beginParse();
Expand All @@ -33,11 +33,11 @@ fun onExternalMessage(inMsgBody: slice) {
}

get seqno(): int {
debugPrint(42);
debugPrint(142);
return getContractData().beginParse().preloadUint(32);
}

get unique(): int {
debugPrint(42);
debugPrint(143);
return getContractData().beginParse().skipBits(32).preloadUint(32);
}
2 changes: 1 addition & 1 deletion cell/src/main/java/org/ton/java/tlb/types/MessageFees.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void printMessageFees() {
public static void printMessageFeesHeader() {
String header =
"| in/out | type | op | value | fwdFee | ihrFee | importFee | timestamp | lt | src | dst |";
System.out.println("Messages");
System.out.println("\nMessages");
System.out.println(
"---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------");
System.out.println(header);
Expand Down
2 changes: 1 addition & 1 deletion cell/src/main/java/org/ton/java/tlb/types/Transaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ public void printAllMessages(boolean withHeader) {
}

public static void printTxHeader() {
System.out.println("Transactions");
System.out.println("\nTransactions");
System.out.println(
"------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------");
System.out.println(
Expand Down
85 changes: 79 additions & 6 deletions emulator/src/main/java/org/ton/java/emulator/tvm/TvmEmulator.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import com.google.gson.GsonBuilder;
import com.google.gson.ToNumberPolicy;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinNT;
import java.math.BigInteger;
import java.util.Collections;
import lombok.Builder;
Expand Down Expand Up @@ -61,8 +63,11 @@ public TvmEmulator build() {

super.tvmEmulatorI = Native.load(super.pathToEmulatorSharedLib, TvmEmulatorI.class);
if (isNull(super.verbosityLevel)) {
super.verbosityLevel = TvmVerbosityLevel.WITH_ALL_STACK_VALUES;
super.verbosityLevel = TvmVerbosityLevel.TRUNCATED;
}

redirectNativeOutput();

if (isNull(super.codeBoc)) {
throw new Error("codeBoc is not set");
}
Expand All @@ -73,6 +78,10 @@ public TvmEmulator build() {
super.tvmEmulatorI.tvm_emulator_create(
super.codeBoc, super.dataBoc, super.verbosityLevel.ordinal());

if (super.verbosityLevel == TvmVerbosityLevel.WITH_ALL_STACK_VALUES) {
super.tvmEmulatorI.tvm_emulator_set_debug_enabled(super.tvmEmulator, true);
}

if (super.tvmEmulator == 0) {
throw new Error("Can't create emulator instance");
}
Expand Down Expand Up @@ -102,13 +111,19 @@ public boolean setLibs(String libsBoc) {
}

/**
* Prepares the c7 tuple (virtual machine context) for a compute phase of a transaction.
*
* <p>C7 tlb-scheme FYI:
*
* <p>smc_info#076ef1ea actions:uint16 msgs_sent:uint16 unixtime:uint32 block_lt:uint64
* trans_lt:uint64 rand_seed:bits256 balance_remaining:CurrencyCollection myself:MsgAddressInt
* global_config:(Maybe Cell) = SmartContractInfo;
* <pre>
* Prepares the c7 tuple (virtual machine context) for a compute phase of a transaction.
* C7 tlb-scheme FYI:
* smc_info#076ef1ea
* actions:uint16 msgs_sent:uint16
* unixtime:uint32 block_lt:uint64
* trans_lt:uint64 rand_seed:bits256
* balance_remaining:CurrencyCollection
* myself:MsgAddressInt
* global_config:(Maybe Cell) = SmartContractInfo;
* </pre>
*
* <p>Set c7 parameters
*
Expand Down Expand Up @@ -208,8 +223,28 @@ public GetMethodResult runGetMethod(String methodName) {
return gson.fromJson(result, GetMethodResult.class);
}

/**
* Run get method
*
* @param methodName String method id
* @param stackBoc Base64 encoded BoC serialized stack (VmStack)
* @return Json object with error: { "success": false, "error": "Error description" } Or success:
* { "success": true "vm_log": "...", "vm_exit_code": 0, "stack": "Base64 encoded BoC
* serialized stack (VmStack)", "missing_library": null, "gas_used": 1212 }
*/
public GetMethodResult runGetMethod(String methodName, String stackBoc) {
String result =
tvmEmulatorI.tvm_emulator_run_get_method(
tvmEmulator, Utils.calculateMethodId(methodName), stackBoc);
Gson gson = new GsonBuilder().setObjectToNumberStrategy(ToNumberPolicy.BIG_DECIMAL).create();
return gson.fromJson(result, GetMethodResult.class);
}

public BigInteger runGetSeqNo() {
GetMethodResult methodResult = runGetMethod(Utils.calculateMethodId("seqno"));
if (methodResult.getVm_exit_code() != 0) {
throw new Error("Cannot execute run method (seqno), Error:\n" + methodResult.getVm_log());
}
VmStack stack = methodResult.getStack();
VmStackList vmStackList = stack.getStack();
return VmStackValueTinyInt.deserialize(
Expand All @@ -219,6 +254,10 @@ public BigInteger runGetSeqNo() {

public BigInteger runGetSubWalletId() {
GetMethodResult methodResult = runGetMethod(Utils.calculateMethodId("get_subwallet_id"));
if (methodResult.getVm_exit_code() != 0) {
throw new Error(
"Cannot execute run method (get_subwallet_id), Error:\n" + methodResult.getVm_log());
}
VmStack stack = methodResult.getStack();
VmStackList vmStackList = stack.getStack();
return VmStackValueTinyInt.deserialize(
Expand All @@ -228,6 +267,10 @@ public BigInteger runGetSubWalletId() {

public String runGetPublicKey() {
GetMethodResult methodResult = runGetMethod(Utils.calculateMethodId("get_public_key"));
if (methodResult.getVm_exit_code() != 0) {
throw new Error(
"Cannot execute run method (get_public_key), Error:\n" + methodResult.getVm_log());
}
VmStack stack = methodResult.getStack();
int depth = stack.getDepth();
VmStackList vmStackList = stack.getStack();
Expand Down Expand Up @@ -284,4 +327,34 @@ public SendInternalMessageResult sendInternalMessage(String messageBodyBoc, long
Gson gson = new GsonBuilder().setObjectToNumberStrategy(ToNumberPolicy.BIG_DECIMAL).create();
return gson.fromJson(result, SendInternalMessageResult.class);
}

private static void redirectNativeOutput() {

// Redirect native output on Windows
WinNT.HANDLE originalOut = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_OUTPUT_HANDLE);
WinNT.HANDLE originalErr = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_ERROR_HANDLE);

// try (FileOutputStream nulStream = new FileOutputStream("NUL")) {
WinNT.HANDLE hNul =
Kernel32.INSTANCE.CreateFile(
"NUL",
Kernel32.GENERIC_WRITE,
Kernel32.FILE_SHARE_WRITE,
null,
Kernel32.OPEN_EXISTING,
0,
null);

// Redirect stdout and stderr to NUL
Kernel32.INSTANCE.SetStdHandle(Kernel32.STD_OUTPUT_HANDLE, hNul);
Kernel32.INSTANCE.SetStdHandle(Kernel32.STD_ERROR_HANDLE, hNul);

// // Close the handle to NUL
// Kernel32.INSTANCE.CloseHandle(hNul);
// } finally {
// // Restore original stdout and stderr
// Kernel32.INSTANCE.SetStdHandle(Kernel32.STD_OUTPUT_HANDLE, originalOut);
// Kernel32.INSTANCE.SetStdHandle(Kernel32.STD_ERROR_HANDLE, originalErr);
// }
}
}
15 changes: 10 additions & 5 deletions emulator/src/main/java/org/ton/java/emulator/tx/TxEmulator.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ public TxEmulator build() {

super.txEmulatorI = Native.load(super.pathToEmulatorSharedLib, TxEmulatorI.class);

redirectNativeOutput();

if (isNull(super.verbosityLevel)) {
super.verbosityLevel = TxVerbosityLevel.WITH_ALL_STACK_VALUES;
super.verbosityLevel = TxVerbosityLevel.TRUNCATED;
}

redirectNativeOutput();

if (isNull(super.configType)) {
super.configType = TxEmulatorConfig.MAINNET;
// log.info("Using default TxEmulator Config - MAINNET");
}

String configBoc = "";
Expand Down Expand Up @@ -103,7 +103,12 @@ public TxEmulator build() {
super.txEmulatorI.transaction_emulator_create(
configBoc, super.verbosityLevel.ordinal());

super.txEmulatorI.emulator_set_verbosity_level(super.txEmulator, 0);
super.txEmulatorI.emulator_set_verbosity_level(
super.txEmulator, super.verbosityLevel.ordinal());

if (super.verbosityLevel == TxVerbosityLevel.WITH_ALL_STACK_VALUES) {
super.txEmulatorI.transaction_emulator_set_debug_enabled(super.txEmulator, true);
}

if (super.txEmulator == 0) {
throw new Error("Can't create tx emulator instance");
Expand Down

0 comments on commit 634625b

Please sign in to comment.