com.radiance.tonclient.Tvm Maven / Gradle / Ivy
Show all versions of ton-client-binding Show documentation
package com.radiance.tonclient;
import java.util.concurrent.CompletableFuture;
import java.util.stream.*;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Arrays;
/**
*
*/
public class Tvm {
/**
*
*/
public static class ExecutionOptions {
public ExecutionOptions(String blockchainConfig, Number blockTime, Long blockLt, Long transactionLt) {
this.blockchainConfig = blockchainConfig;
this.blockTime = blockTime;
this.blockLt = blockLt;
this.transactionLt = transactionLt;
}
public ExecutionOptions(String blockchainConfig, Number blockTime, Long blockLt) {
this.blockchainConfig = blockchainConfig;
this.blockTime = blockTime;
this.blockLt = blockLt;
}
public ExecutionOptions(String blockchainConfig, Number blockTime) {
this.blockchainConfig = blockchainConfig;
this.blockTime = blockTime;
}
public ExecutionOptions(String blockchainConfig) {
this.blockchainConfig = blockchainConfig;
}
public ExecutionOptions() {
}
@JsonProperty("blockchain_config")
private String blockchainConfig;
/**
*
*/
public String getBlockchainConfig() {
return blockchainConfig;
}
/**
*
*/
public void setBlockchainConfig(String value) {
this.blockchainConfig = value;
}
@JsonProperty("block_time")
private Number blockTime;
/**
*
*/
public Number getBlockTime() {
return blockTime;
}
/**
*
*/
public void setBlockTime(Number value) {
this.blockTime = value;
}
@JsonProperty("block_lt")
private Long blockLt;
/**
*
*/
public Long getBlockLt() {
return blockLt;
}
/**
*
*/
public void setBlockLt(Long value) {
this.blockLt = value;
}
@JsonProperty("transaction_lt")
private Long transactionLt;
/**
*
*/
public Long getTransactionLt() {
return transactionLt;
}
/**
*
*/
public void setTransactionLt(Long value) {
this.transactionLt = value;
}
@Override
public String toString() {
return "{"+Stream.of((blockchainConfig==null?null:("\"blockchain_config\":\""+blockchainConfig+"\"")),(blockTime==null?null:("\"block_time\":"+blockTime)),(blockLt==null?null:("\"block_lt\":"+blockLt)),(transactionLt==null?null:("\"transaction_lt\":"+transactionLt))).filter(_f -> _f != null).collect(Collectors.joining(","))+"}";
}
}
public static abstract class AccountForExecutor {
public static final None None = new None();
/**
*
*/
public static class None extends AccountForExecutor {
public None() {
}
@Override
public String toString() {
return "{"+"\"type\":\"None\""+"}";
}
}
public static final Uninit Uninit = new Uninit();
/**
*
*/
public static class Uninit extends AccountForExecutor {
public Uninit() {
}
@Override
public String toString() {
return "{"+"\"type\":\"Uninit\""+"}";
}
}
/**
*
*/
public static class Account extends AccountForExecutor {
public Account(String boc, Boolean unlimitedBalance) {
this.boc = boc;
this.unlimitedBalance = unlimitedBalance;
}
public Account(String boc) {
this.boc = boc;
}
public Account() {
}
@JsonProperty("boc")
private String boc;
/**
* Encoded as base64.
*/
public String getBoc() {
return boc;
}
/**
* Encoded as base64.
*/
public void setBoc(String value) {
this.boc = value;
}
@JsonProperty("unlimited_balance")
private Boolean unlimitedBalance;
/**
* Can be used to calculate transaction fees without balance check
*/
public Boolean getUnlimitedBalance() {
return unlimitedBalance;
}
/**
* Can be used to calculate transaction fees without balance check
*/
public void setUnlimitedBalance(Boolean value) {
this.unlimitedBalance = value;
}
@Override
public String toString() {
return "{"+Stream.of("\"type\":\"Account\"",(boc==null?null:("\"boc\":\""+boc+"\"")),(unlimitedBalance==null?null:("\"unlimited_balance\":"+unlimitedBalance))).filter(_f -> _f != null).collect(Collectors.joining(","))+"}";
}
}
}
/**
*
*/
public static class TransactionFees {
public TransactionFees(Long inMsgFwdFee, Long storageFee, Long gasFee, Long outMsgsFwdFee, Long totalAccountFees, Long totalOutput) {
this.inMsgFwdFee = inMsgFwdFee;
this.storageFee = storageFee;
this.gasFee = gasFee;
this.outMsgsFwdFee = outMsgsFwdFee;
this.totalAccountFees = totalAccountFees;
this.totalOutput = totalOutput;
}
public TransactionFees(Long inMsgFwdFee, Long storageFee, Long gasFee, Long outMsgsFwdFee, Long totalAccountFees) {
this.inMsgFwdFee = inMsgFwdFee;
this.storageFee = storageFee;
this.gasFee = gasFee;
this.outMsgsFwdFee = outMsgsFwdFee;
this.totalAccountFees = totalAccountFees;
}
public TransactionFees(Long inMsgFwdFee, Long storageFee, Long gasFee, Long outMsgsFwdFee) {
this.inMsgFwdFee = inMsgFwdFee;
this.storageFee = storageFee;
this.gasFee = gasFee;
this.outMsgsFwdFee = outMsgsFwdFee;
}
public TransactionFees(Long inMsgFwdFee, Long storageFee, Long gasFee) {
this.inMsgFwdFee = inMsgFwdFee;
this.storageFee = storageFee;
this.gasFee = gasFee;
}
public TransactionFees(Long inMsgFwdFee, Long storageFee) {
this.inMsgFwdFee = inMsgFwdFee;
this.storageFee = storageFee;
}
public TransactionFees(Long inMsgFwdFee) {
this.inMsgFwdFee = inMsgFwdFee;
}
public TransactionFees() {
}
@JsonProperty("in_msg_fwd_fee")
private Long inMsgFwdFee;
/**
*
*/
public Long getInMsgFwdFee() {
return inMsgFwdFee;
}
/**
*
*/
public void setInMsgFwdFee(Long value) {
this.inMsgFwdFee = value;
}
@JsonProperty("storage_fee")
private Long storageFee;
/**
*
*/
public Long getStorageFee() {
return storageFee;
}
/**
*
*/
public void setStorageFee(Long value) {
this.storageFee = value;
}
@JsonProperty("gas_fee")
private Long gasFee;
/**
*
*/
public Long getGasFee() {
return gasFee;
}
/**
*
*/
public void setGasFee(Long value) {
this.gasFee = value;
}
@JsonProperty("out_msgs_fwd_fee")
private Long outMsgsFwdFee;
/**
*
*/
public Long getOutMsgsFwdFee() {
return outMsgsFwdFee;
}
/**
*
*/
public void setOutMsgsFwdFee(Long value) {
this.outMsgsFwdFee = value;
}
@JsonProperty("total_account_fees")
private Long totalAccountFees;
/**
*
*/
public Long getTotalAccountFees() {
return totalAccountFees;
}
/**
*
*/
public void setTotalAccountFees(Long value) {
this.totalAccountFees = value;
}
@JsonProperty("total_output")
private Long totalOutput;
/**
*
*/
public Long getTotalOutput() {
return totalOutput;
}
/**
*
*/
public void setTotalOutput(Long value) {
this.totalOutput = value;
}
@Override
public String toString() {
return "{"+Stream.of((inMsgFwdFee==null?null:("\"in_msg_fwd_fee\":"+inMsgFwdFee)),(storageFee==null?null:("\"storage_fee\":"+storageFee)),(gasFee==null?null:("\"gas_fee\":"+gasFee)),(outMsgsFwdFee==null?null:("\"out_msgs_fwd_fee\":"+outMsgsFwdFee)),(totalAccountFees==null?null:("\"total_account_fees\":"+totalAccountFees)),(totalOutput==null?null:("\"total_output\":"+totalOutput))).filter(_f -> _f != null).collect(Collectors.joining(","))+"}";
}
}
/**
*
*/
public static class ResultOfRunExecutor {
public ResultOfRunExecutor(Object transaction, String[] outMessages, Processing.DecodedOutput decoded, String account, TransactionFees fees) {
this.transaction = transaction;
this.outMessages = outMessages;
this.decoded = decoded;
this.account = account;
this.fees = fees;
}
public ResultOfRunExecutor(Object transaction, String[] outMessages, Processing.DecodedOutput decoded, String account) {
this.transaction = transaction;
this.outMessages = outMessages;
this.decoded = decoded;
this.account = account;
}
public ResultOfRunExecutor(Object transaction, String[] outMessages, Processing.DecodedOutput decoded) {
this.transaction = transaction;
this.outMessages = outMessages;
this.decoded = decoded;
}
public ResultOfRunExecutor(Object transaction, String[] outMessages) {
this.transaction = transaction;
this.outMessages = outMessages;
}
public ResultOfRunExecutor(Object transaction) {
this.transaction = transaction;
}
public ResultOfRunExecutor() {
}
@JsonProperty("transaction")
private Object transaction;
/**
* In addition to the regular transaction fields there is a`boc` field encoded with `base64` which contains sourcetransaction BOC.
*/
public Object getTransaction() {
return transaction;
}
/**
* In addition to the regular transaction fields there is a`boc` field encoded with `base64` which contains sourcetransaction BOC.
*/
public void setTransaction(Object value) {
this.transaction = value;
}
@JsonProperty("out_messages")
private String[] outMessages;
/**
* Encoded as `base64`
*/
public String[] getOutMessages() {
return outMessages;
}
/**
* Encoded as `base64`
*/
public void setOutMessages(String[] value) {
this.outMessages = value;
}
@JsonProperty("decoded")
private Processing.DecodedOutput decoded;
/**
*
*/
public Processing.DecodedOutput getDecoded() {
return decoded;
}
/**
*
*/
public void setDecoded(Processing.DecodedOutput value) {
this.decoded = value;
}
@JsonProperty("account")
private String account;
/**
* Encoded as `base64`
*/
public String getAccount() {
return account;
}
/**
* Encoded as `base64`
*/
public void setAccount(String value) {
this.account = value;
}
@JsonProperty("fees")
private TransactionFees fees;
/**
*
*/
public TransactionFees getFees() {
return fees;
}
/**
*
*/
public void setFees(TransactionFees value) {
this.fees = value;
}
@Override
public String toString() {
return "{"+Stream.of((transaction==null?null:("\"transaction\":"+transaction)),(outMessages==null?null:("\"out_messages\":\""+Arrays.toString(outMessages)+"\"")),(decoded==null?null:("\"decoded\":"+decoded)),(account==null?null:("\"account\":\""+account+"\"")),(fees==null?null:("\"fees\":"+fees))).filter(_f -> _f != null).collect(Collectors.joining(","))+"}";
}
}
/**
*
*/
public static class ResultOfRunTvm {
public ResultOfRunTvm(String[] outMessages, Processing.DecodedOutput decoded, String account) {
this.outMessages = outMessages;
this.decoded = decoded;
this.account = account;
}
public ResultOfRunTvm(String[] outMessages, Processing.DecodedOutput decoded) {
this.outMessages = outMessages;
this.decoded = decoded;
}
public ResultOfRunTvm(String[] outMessages) {
this.outMessages = outMessages;
}
public ResultOfRunTvm() {
}
@JsonProperty("out_messages")
private String[] outMessages;
/**
* Encoded as `base64`
*/
public String[] getOutMessages() {
return outMessages;
}
/**
* Encoded as `base64`
*/
public void setOutMessages(String[] value) {
this.outMessages = value;
}
@JsonProperty("decoded")
private Processing.DecodedOutput decoded;
/**
*
*/
public Processing.DecodedOutput getDecoded() {
return decoded;
}
/**
*
*/
public void setDecoded(Processing.DecodedOutput value) {
this.decoded = value;
}
@JsonProperty("account")
private String account;
/**
* Encoded as `base64`. Attention! Only `account_state.storage.state.data` part of the BOC is updated.
*/
public String getAccount() {
return account;
}
/**
* Encoded as `base64`. Attention! Only `account_state.storage.state.data` part of the BOC is updated.
*/
public void setAccount(String value) {
this.account = value;
}
@Override
public String toString() {
return "{"+Stream.of((outMessages==null?null:("\"out_messages\":\""+Arrays.toString(outMessages)+"\"")),(decoded==null?null:("\"decoded\":"+decoded)),(account==null?null:("\"account\":\""+account+"\""))).filter(_f -> _f != null).collect(Collectors.joining(","))+"}";
}
}
private TONContext context;
public Tvm(TONContext context) {
this.context = context;
}
/**
* Performs all the phases of contract execution on Transaction Executor -the same component that is used on Validator Nodes.Can be used for contract debugging, to find out the reason why a message was not delivered successfully.Validators throw away the failed external inbound messages (if they failed bedore `ACCEPT`) in the real network.This is why these messages are impossible to debug in the real network.With the help of run_executor you can do that. In fact, `process_message` functionperforms local check with `run_executor` if there was no transaction as a result of processingand returns the error, if there is one.
Another use case to use `run_executor` is to estimate fees for message execution.Set `AccountForExecutor::Account.unlimited_balance`to `true` so that emulation will not depend on the actual balance.This may be needed to calculate deploy fees for an account that does not exist yet.JSON with fees is in `fees` field of the result.
One more use case - you can produce the sequence of operations,thus emulating the sequential contract calls locally.And so on.
Transaction executor requires account BOC (bag of cells) as a parameter.To get the account BOC - use `net.query` method to download it from GraphQL API(field `boc` of `account`) or generate it with `abi.encode_account` method.
Also it requires message BOC. To get the message BOC - use `abi.encode_message` or `abi.encode_internal_message`.
If you need this emulation to be as precise as possible (for instance - emulate transactionwith particular lt in particular block or use particular blockchain config,downloaded from a particular key block - then specify `execution_options` parameter.
If you need to see the aborted transaction as a result, not as an error, set `skip_transaction_check` to `true`.
*
* @param message Must be encoded as base64.
* @param account
* @param executionOptions
* @param abi
* @param skipTransactionCheck
* @param bocCache The BOC itself returned if no cache type provided
* @param returnUpdatedAccount Empty string is returned if the flag is `false`
*/
public CompletableFuture runExecutor(String message, AccountForExecutor account, ExecutionOptions executionOptions, Abi.ABI abi, Boolean skipTransactionCheck, Boc.BocCacheType bocCache, Boolean returnUpdatedAccount) {
return context.requestJSON("tvm.run_executor", "{"+Stream.of((message==null?null:("\"message\":\""+message+"\"")),(account==null?null:("\"account\":"+account)),(executionOptions==null?null:("\"execution_options\":"+executionOptions)),(abi==null?null:("\"abi\":"+abi)),(skipTransactionCheck==null?null:("\"skip_transaction_check\":"+skipTransactionCheck)),(bocCache==null?null:("\"boc_cache\":"+bocCache)),(returnUpdatedAccount==null?null:("\"return_updated_account\":"+returnUpdatedAccount))).filter(_f -> _f != null).collect(Collectors.joining(","))+"}")
.thenApply(json -> TONContext.convertValue(json, ResultOfRunExecutor.class));
}
/**
* Performs only a part of compute phase of transaction executionthat is used to run get-methods of ABI-compatible contracts.If you try to run get-methods with `run_executor` you will get an error, because it checks ACCEPT and exitsif there is none, which is actually true for get-methods.
To get the account BOC (bag of cells) - use `net.query` method to download it from GraphQL API(field `boc` of `account`) or generate it with `abi.encode_account method`.To get the message BOC - use `abi.encode_message` or prepare it any other way, for instance, with FIFT script.
Attention! Updated account state is produces as well, but only`account_state.storage.state.data` part of the BOC is updated.
*
* @param message Must be encoded as base64.
* @param account Must be encoded as base64.
* @param executionOptions
* @param abi
* @param bocCache The BOC itself returned if no cache type provided
* @param returnUpdatedAccount Empty string is returned if the flag is `false`
*/
public CompletableFuture runTvm(String message, String account, ExecutionOptions executionOptions, Abi.ABI abi, Boc.BocCacheType bocCache, Boolean returnUpdatedAccount) {
return context.requestJSON("tvm.run_tvm", "{"+Stream.of((message==null?null:("\"message\":\""+message+"\"")),(account==null?null:("\"account\":\""+account+"\"")),(executionOptions==null?null:("\"execution_options\":"+executionOptions)),(abi==null?null:("\"abi\":"+abi)),(bocCache==null?null:("\"boc_cache\":"+bocCache)),(returnUpdatedAccount==null?null:("\"return_updated_account\":"+returnUpdatedAccount))).filter(_f -> _f != null).collect(Collectors.joining(","))+"}")
.thenApply(json -> TONContext.convertValue(json, ResultOfRunTvm.class));
}
/**
* Executes a get-method of FIFT contract that fulfills the smc-guidelines https://test.ton.org/smc-guidelines.txtand returns the result data from TVM's stack
*
* @param account
* @param functionName
* @param input
* @param executionOptions
* @param tupleListAsArray Default is `false`. Input parameters may use any of lists representationsIf you receive this error on Web: "Runtime error. Unreachable code should not be executed...",set this flag to true.This may happen, for example, when elector contract contains too many participants
*/
public CompletableFuture