diff --git a/Makefile b/Makefile index 20d88ed92..81f6012c3 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -UNIT_TAGS := "$(subst :, or ,$(shell awk '{print $2}' src/test/unit.tags | paste -s -d: -))" -INTEGRATION_TAGS := "$(subst :, or ,$(shell awk '{print $2}' src/test/integration.tags | paste -s -d: -))" +UNIT_TAGS := "($(subst :, or ,$(shell awk '{print $2}' src/test/unit.tags | paste -s -d: -))) and not @falcon-1024" +INTEGRATION_TAGS := "($(subst :, or ,$(shell awk '{print $2}' src/test/integration.tags | paste -s -d: -))) and not @falcon-1024" unit: mvn test -Dcucumber.filter.tags=$(UNIT_TAGS) diff --git a/examples/src/main/java/com/algorand/examples/Debug.java b/examples/src/main/java/com/algorand/examples/Debug.java deleted file mode 100644 index d0a06d714..000000000 --- a/examples/src/main/java/com/algorand/examples/Debug.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.algorand.examples; - -import java.io.FileOutputStream; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; - -import com.algorand.algosdk.abi.Contract; -import com.algorand.algosdk.account.Account; -import com.algorand.algosdk.builder.transaction.MethodCallTransactionBuilder; -import com.algorand.algosdk.transaction.AtomicTransactionComposer; -import com.algorand.algosdk.transaction.MethodCallParams; -import com.algorand.algosdk.transaction.Transaction; -import com.algorand.algosdk.util.Encoder; -import com.algorand.algosdk.v2.client.Utils; -import com.algorand.algosdk.v2.client.common.AlgodClient; -import com.algorand.algosdk.v2.client.common.Response; -import com.algorand.algosdk.v2.client.model.DryrunRequest; -import com.algorand.algosdk.v2.client.model.DryrunResponse; -import com.algorand.algosdk.v2.client.model.DryrunTxnResult; -import com.algorand.algosdk.v2.client.model.TransactionParametersResponse; - -public class Debug { - - - public static void main(String[] args) throws Exception { - AlgodClient algodClient = ExampleUtils.getAlgodClient(); - List accts = ExampleUtils.getSandboxAccounts(); - Account acct = accts.get(0); - - Long appId = ATC.deployApp(algodClient, acct); - - String jsonContract = Files.readString(Paths.get("calculator/contract.json")); - Contract contract = Encoder.decodeFromJson(jsonContract, Contract.class); - - // example: DEBUG_DRYRUN_DUMP - // Set up the transactions we'd like to dryrun - AtomicTransactionComposer atc = new AtomicTransactionComposer(); - - List methodArgs = new ArrayList(); - methodArgs.add(1); - methodArgs.add(1); - - TransactionParametersResponse sp = algodClient.TransactionParams().execute().body(); - - MethodCallTransactionBuilder mctb = MethodCallTransactionBuilder.Builder(); - MethodCallParams mcp = mctb.applicationId(appId).signer(acct.getTransactionSigner()) - .suggestedParams(sp) - .sender(acct.getAddress()) - .method(contract.getMethodByName("add")) - .methodArguments(methodArgs) - .onComplete(Transaction.OnCompletion.NoOpOC) - .build(); - atc.addMethodCall(mcp); - - DryrunRequest drr = Utils.createDryrun(algodClient, atc.gatherSignatures(), "", 0L, 0L); - - FileOutputStream outfile = new FileOutputStream("my-dryrun.msgpack"); - outfile.write(Encoder.encodeToMsgPack(drr)); - outfile.close(); - // example: DEBUG_DRYRUN_DUMP - - // example: DEBUG_DRYRUN_SUBMIT - Response resp = algodClient.TealDryrun().request(drr).execute(); - DryrunResponse drResp = resp.body(); - DryrunTxnResult dryrunTxnResult = drResp.txns.get(0); - System.out.println(dryrunTxnResult.appCallMessages); - System.out.println(Utils.appTrace(dryrunTxnResult)); - // example: DEBUG_DRYRUN_SUBMIT - } -} diff --git a/src/main/java/com/algorand/algosdk/v2/client/Utils.java b/src/main/java/com/algorand/algosdk/v2/client/Utils.java index 3f87f1e1a..7e380c020 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/Utils.java +++ b/src/main/java/com/algorand/algosdk/v2/client/Utils.java @@ -1,331 +1,12 @@ package com.algorand.algosdk.v2.client; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.HashSet; -import java.util.Set; - -import com.algorand.algosdk.crypto.Address; -import com.algorand.algosdk.transaction.SignedTransaction; -import com.algorand.algosdk.transaction.Transaction; -import com.algorand.algosdk.transaction.Transaction.Type; -import com.algorand.algosdk.util.Encoder; import com.algorand.algosdk.v2.client.common.AlgodClient; import com.algorand.algosdk.v2.client.common.Response; -import com.algorand.algosdk.v2.client.model.DryrunRequest; -import com.algorand.algosdk.v2.client.model.DryrunState; -import com.algorand.algosdk.v2.client.model.DryrunTxnResult; -import com.algorand.algosdk.v2.client.model.Application; -import com.algorand.algosdk.v2.client.model.ApplicationParams; -import com.algorand.algosdk.v2.client.model.ApplicationStateSchema; -import com.algorand.algosdk.v2.client.model.Account; -import com.algorand.algosdk.v2.client.model.Asset; import com.algorand.algosdk.v2.client.model.NodeStatusResponse; import com.algorand.algosdk.v2.client.model.PendingTransactionResponse; -import com.algorand.algosdk.v2.client.model.TealValue; - -import org.apache.commons.lang3.StringUtils; public class Utils { - // https://github.com/algorand/go-algorand/blob/e466aa18d4d963868d6d15279b1c881977fa603f/libgoal/libgoal.go#L1089-L1090 - private static final Long defaultAppId = 1380011588L; - private static final int defaultMaxWidth = 30; - - /** - * Construct a DryrunRequest object from a set of transactions. - * A DryrunRequest is composed of static balance information. This function uses - * the ApplicationCall transaction - * parameters to infer what Application State and Account balance information to - * query using the client and adds it to the DryrunRequest object. - * If foreign assets are passed, it will also add the creators balance - * information to the DryrunRequest. - * - * @param client an Algod v2 client - * @param txns the array of SignedTransactions that should be used - * to generate the DryrunRequest - * @return DryrunRequest to be submitted to TealDryrun endpoint - * @throws Exception if transaction is rejected or the transaction is not - * confirmed before wait round - * - */ - public static DryrunRequest createDryrun(AlgodClient client, List txns) throws Exception { - return Utils.createDryrun(client, txns, "", 0L, 0L); - } - - /** - * Construct a DryrunRequest object from a set of transactions. - * A DryrunRequest is composed of static balance information. This function uses - * the ApplicationCall transaction - * parameters to infer what Application State and Account balance information to - * query using the client and adds it to the DryrunRequest object. - * If foreign assets are passed, it will also add the creators balance - * information to the DryrunRequest. - * - * @param client an Algod v2 client - * @param txns the array of SignedTransactions that should be used - * to generate the DryrunRequest - * @param protocol_version The protocol version the dryrun should include - * @param latest_timestamp The latest timestamp the dryrun should include - * @param round The agreement round or block height the dryrun should - * include - * @return DryrunRequest to be submitted to TealDryrun endpoint - * @throws Exception if transaction is rejected or the transaction is not - * confirmed before wait round - */ - public static DryrunRequest createDryrun(AlgodClient client, List txns, String protocol_version, - Long latest_timestamp, Long round) - throws Exception { - - if (client == null || txns.size() == 0) { - throw new IllegalArgumentException("Bad arguments for createDryrun."); - } - - // The details we need to add to DryrunRequest object - ArrayList app_infos = new ArrayList<>(); - ArrayList acct_infos = new ArrayList<>(); - - // These are populated from the transactions passed - Set apps = new HashSet<>(); - Set assets = new HashSet<>(); - Set accts = new HashSet<>(); - - for (SignedTransaction txn : txns) { - Transaction tx = txn.tx; - - // We're only interested to pull state for app calls - if (tx.type != Type.ApplicationCall) { - continue; - } - - // If this is a create transaction - if (tx.applicationId == 0 || tx.applicationId == null) { - // Prepare and set param fields for Application being created - // from the transaction passed - ApplicationParams params = new ApplicationParams(); - params.creator = tx.sender; - params.approvalProgram = tx.approvalProgram.getBytes(); - params.clearStateProgram = tx.clearStateProgram.getBytes(); - - ApplicationStateSchema localState = new ApplicationStateSchema(); - localState.numByteSlice = tx.localStateSchema.numByteSlice.longValue(); - localState.numUint = tx.localStateSchema.numUint.longValue(); - params.localStateSchema = localState; - - ApplicationStateSchema globalState = new ApplicationStateSchema(); - globalState.numByteSlice = tx.globalStateSchema.numByteSlice.longValue(); - globalState.numUint = tx.globalStateSchema.numUint.longValue(); - params.globalStateSchema = globalState; - - Application app = new Application(); - app.id = Utils.defaultAppId; - app.params = params; - - app_infos.add(app); - } else { - apps.add(tx.applicationId); - accts.add(Address.forApplication(tx.applicationId).toString()); - } - - if (tx.foreignApps.size() > 0) { - apps.addAll(tx.foreignApps); - for(Long aidx: tx.foreignApps){ - accts.add(Address.forApplication(aidx).toString()); - } - } - - if (tx.foreignAssets.size() > 0) { - assets.addAll(tx.foreignAssets); - } - - if (tx.accounts.size() > 0) { - for (Address acct : tx.accounts) { - accts.add(acct.toString()); - } - } - } - - for (Long asset : assets) { - Response ar = client.GetAssetByID(asset).execute(); - if (ar.isSuccessful()) { - Asset a = ar.body(); - accts.add(a.params.creator); - } - } - - for (Long app : apps) { - Response ar = client.GetApplicationByID(app).execute(); - if (ar.isSuccessful()) { - app_infos.add(ar.body()); - accts.add(ar.body().params.creator.toString()); - } - } - - for (String acct : accts) { - Response ar = client.AccountInformation(new Address(acct)).execute(); - if (ar.isSuccessful()) { - acct_infos.add(ar.body()); - } - } - - DryrunRequest drr = new DryrunRequest(); - drr.accounts = acct_infos; - drr.apps = app_infos; - drr.txns = txns; - drr.protocolVersion = protocol_version; - drr.latestTimestamp = latest_timestamp; - drr.round = BigInteger.valueOf(round); - return drr; - } - - /** - * StackPrinterConfig contains configuration parameters for - * printing the trace from a DryrunTxnResult. - */ - public static class StackPrinterConfig { - public int maxValueWidth = 0; - public boolean topOfStackFirst = false; - } - - private static String truncate(String s, int maxWidth) { - if (s.length() > maxWidth && maxWidth > 0) { - return s.substring(0, maxWidth) + "..."; - } - return s; - } - - private static String stackToString(List stack, boolean reverse) { - if (reverse) { - Collections.reverse(stack); - } - - List elems = new ArrayList(); - for (int i = 0; i < stack.size(); i++) { - TealValue tv = stack.get(i); - switch (tv.type.intValue()) { - case 1: - byte[] decoded = Encoder.decodeFromBase64(tv.bytes); - elems.add("0x" + Encoder.encodeToHexStr(decoded)); - break; - case 2: - elems.add(tv.uint.toString()); - break; - default: - break; - } - } - - return String.format("[%s]", StringUtils.join(elems, ", ")); - } - - private static String scratchToString(List prevScratch, List currScratch) { - if (currScratch.size() == 0) - return ""; - - int newIdx = -1; - for (int i = 0; i < currScratch.size(); i++) { - if (i >= prevScratch.size()) { - newIdx = i; - continue; - } - - if (!Objects.deepEquals(prevScratch.get(i), currScratch.get(i))) { - newIdx = i; - } - } - - if (newIdx < 0) - return ""; - - TealValue tv = currScratch.get(newIdx); - if (tv.bytes.length() > 0) { - byte[] decoded = Encoder.decodeFromBase64(tv.bytes); - String newValue = "0x" + Encoder.encodeToHexStr(decoded); - return String.format("%d = %s", newIdx, newValue); - } - return String.format("%d = %d", newIdx, tv.uint); - } - - private static String trace(List state, List disassembly, StackPrinterConfig spc) { - List lines = new ArrayList(); - lines.add(new String[] { "pc#", "ln#", "source", "scratch", "stack" }); - - // Create lines for trace - for (int i = 0; i < state.size(); i++) { - DryrunState s = state.get(i); - - boolean hasError = s.error != null && s.error != ""; - String src = hasError ? String.format("!! %s !!", s.error) : disassembly.get(s.line.intValue()); - - List currScratch = s.scratch; - List prevScratch = i > 0 ? state.get(i - 1).scratch : new ArrayList(); - - lines.add(new String[] { - String.format("%-3d", s.pc), - String.format("%-3d", s.line), - truncate(src, spc.maxValueWidth), - truncate(scratchToString(prevScratch, currScratch), spc.maxValueWidth), - truncate(stackToString(s.stack, spc.topOfStackFirst), spc.maxValueWidth) - }); - } - - // Get max length of each column - int columns = lines.get(0).length; - int[] maxLengths = new int[columns]; - for (int i = 0; i < lines.size(); i++) { - String[] line = lines.get(i); - for (int j = 0; j < columns; j++) { - if (line[j].length() > maxLengths[j]) { - maxLengths[j] = line[j].length(); - } - } - } - - // Create formatter - List fmts = new ArrayList(); - for (int i = 0; i < columns; i++) { - fmts.add(String.format("%%-%ds", maxLengths[i] + 1)); - } - - String fmt = StringUtils.join(fmts, "|"); - StringBuilder sb = new StringBuilder(); - for (String[] line : lines) { - sb.append(String.format(fmt, line).trim() + "\n"); - } - return sb.toString(); - } - - public static String appTrace(DryrunTxnResult dtr) { - StackPrinterConfig spc = new StackPrinterConfig(); - spc.maxValueWidth = defaultMaxWidth; - spc.topOfStackFirst = true; - return trace( - dtr.appCallTrace, - dtr.disassembly, - spc); - } - - public static String appTrace(DryrunTxnResult dtr, StackPrinterConfig spc) { - return trace(dtr.appCallTrace, dtr.disassembly, spc); - } - - public static String lsigTrace(DryrunTxnResult dtr) { - StackPrinterConfig spc = new StackPrinterConfig(); - spc.maxValueWidth = defaultMaxWidth; - spc.topOfStackFirst = true; - return trace( - dtr.logicSigTrace, - dtr.logicSigDisassembly, - spc); - } - - public static String lsigTrace(DryrunTxnResult dtr, StackPrinterConfig spc) { - return trace(dtr.logicSigTrace, dtr.logicSigDisassembly, spc); - } - /** * Wait until a transaction has been confirmed or rejected by the network * or wait until waitRound fully elapsed diff --git a/src/main/java/com/algorand/algosdk/v2/client/algod/GetApplicationBoxes.java b/src/main/java/com/algorand/algosdk/v2/client/algod/GetApplicationBoxes.java index 2b72423ee..ba0e90008 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/algod/GetApplicationBoxes.java +++ b/src/main/java/com/algorand/algosdk/v2/client/algod/GetApplicationBoxes.java @@ -1,17 +1,31 @@ package com.algorand.algosdk.v2.client.algod; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + import com.algorand.algosdk.v2.client.common.Client; import com.algorand.algosdk.v2.client.common.HttpMethod; import com.algorand.algosdk.v2.client.common.Query; import com.algorand.algosdk.v2.client.common.QueryData; import com.algorand.algosdk.v2.client.common.Response; import com.algorand.algosdk.v2.client.model.BoxesResponse; +import com.algorand.algosdk.v2.client.model.Enums; /** - * Given an application ID, return all Box names. No particular ordering is + * Given an application ID, return all box names. No particular ordering is * guaranteed. Request fails when client or server-side configured limits prevent - * returning all Box names. + * returning all box names. + * Pagination mode is enabled when any of the following parameters are provided: + * limit, next, prefix, include, or round. In pagination mode box values can be + * requested and results are returned in sorted order. + * To paginate: use the next-token from a previous response as the next parameter + * in the following request. Pin the round parameter to the round value from the + * first page's response to ensure consistent results across pages. The server + * enforces a per-response byte limit, so fewer results than limit may be returned + * even when more exist; the presence of next-token is the only reliable signal + * that more data is available. * /v2/applications/{application-id}/boxes */ public class GetApplicationBoxes extends Query { @@ -26,6 +40,23 @@ public GetApplicationBoxes(Client client, Long applicationId) { this.applicationId = applicationId; } + /** + * Include additional items in the response. Use `values` to include box values. + * Multiple values can be comma-separated. + */ + public GetApplicationBoxes include(List include) { + addQuery("include", StringUtils.join(include, ",")); + return this; + } + + /** + * Maximum number of boxes to return per page. + */ + public GetApplicationBoxes limit(Long limit) { + addQuery("limit", String.valueOf(limit)); + return this; + } + /** * Max number of box names to return. If max is not set, or max == 0, returns all * box-names. @@ -35,6 +66,34 @@ public GetApplicationBoxes max(Long max) { return this; } + /** + * A box name, in the goal app call arg form 'encoding:value', representing the + * earliest box name to include in results. Use the next-token from a previous + * response. + */ + public GetApplicationBoxes next(String next) { + addQuery("next", String.valueOf(next)); + return this; + } + + /** + * A box name prefix, in the goal app call arg form 'encoding:value', to filter + * results by. Only boxes whose names start with this prefix will be returned. + */ + public GetApplicationBoxes prefix(String prefix) { + addQuery("prefix", String.valueOf(prefix)); + return this; + } + + /** + * Return box data from the given round. The round must be within the node's + * available range. + */ + public GetApplicationBoxes round(java.math.BigInteger round) { + addQuery("round", String.valueOf(round)); + return this; + } + /** * Execute the query. * @return the query response object. diff --git a/src/main/java/com/algorand/algosdk/v2/client/algod/RawTransaction.java b/src/main/java/com/algorand/algosdk/v2/client/algod/RawTransaction.java index 91ccc0bdf..a6532b07b 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/algod/RawTransaction.java +++ b/src/main/java/com/algorand/algosdk/v2/client/algod/RawTransaction.java @@ -26,6 +26,17 @@ public RawTransaction rawtxn(byte[] rawtxn) { return this; } + /** + * Skip post-quantum address checks, including the check that rejects PQ authorizer + * and LogicSig escrow (TEAL v13 or later) whose address is an Edwards25519 curve + * point. This should only be used if you understand the risks and know what you + * are doing. + */ + public RawTransaction skipPqAddressCheck(Boolean skipPqAddressCheck) { + addQuery("skip-pq-address-check", String.valueOf(skipPqAddressCheck)); + return this; + } + /** * Execute the query. * @return the query response object. diff --git a/src/main/java/com/algorand/algosdk/v2/client/algod/TealDryrun.java b/src/main/java/com/algorand/algosdk/v2/client/algod/TealDryrun.java deleted file mode 100644 index 5b6f6a766..000000000 --- a/src/main/java/com/algorand/algosdk/v2/client/algod/TealDryrun.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.algorand.algosdk.v2.client.algod; - -import com.algorand.algosdk.util.Encoder; -import com.algorand.algosdk.v2.client.common.Client; -import com.algorand.algosdk.v2.client.common.HttpMethod; -import com.algorand.algosdk.v2.client.common.Query; -import com.algorand.algosdk.v2.client.common.QueryData; -import com.algorand.algosdk.v2.client.common.Response; -import com.algorand.algosdk.v2.client.model.DryrunRequest; -import com.algorand.algosdk.v2.client.model.DryrunResponse; -import com.fasterxml.jackson.core.JsonProcessingException; - - -/** - * Executes TEAL program(s) in context and returns debugging information about the - * execution. This endpoint is only enabled when a node's configuration file sets - * EnableDeveloperAPI to true. - * /v2/teal/dryrun - */ -public class TealDryrun extends Query { - - public TealDryrun(Client client) { - super(client, new HttpMethod("post")); - } - - /** - * Transaction (or group) and any accompanying state-simulation data. - * @throws JsonProcessingException - */ - public TealDryrun request(DryrunRequest request) throws JsonProcessingException { - addToBody(Encoder.encodeToMsgPack(request)); - return this; - } - - /** - * Execute the query. - * @return the query response object. - * @throws Exception - */ - @Override - public Response execute() throws Exception { - Response resp = baseExecute(); - resp.setValueType(DryrunResponse.class); - return resp; - } - - /** - * Execute the query with custom headers, there must be an equal number of keys and values - * or else an error will be generated. - * @param headers an array of header keys - * @param values an array of header values - * @return the query response object. - * @throws Exception - */ - @Override - public Response execute(String[] headers, String[] values) throws Exception { - Response resp = baseExecute(headers, values); - resp.setValueType(DryrunResponse.class); - return resp; - } - - protected QueryData getRequestString() { - addPathSegment(String.valueOf("v2")); - addPathSegment(String.valueOf("teal")); - addPathSegment(String.valueOf("dryrun")); - - return qd; - } -} diff --git a/src/main/java/com/algorand/algosdk/v2/client/common/AlgodClient.java b/src/main/java/com/algorand/algosdk/v2/client/common/AlgodClient.java index ad15d67f3..8b3618792 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/common/AlgodClient.java +++ b/src/main/java/com/algorand/algosdk/v2/client/common/AlgodClient.java @@ -39,7 +39,6 @@ import com.algorand.algosdk.v2.client.algod.SetSyncRound; import com.algorand.algosdk.v2.client.algod.TealCompile; import com.algorand.algosdk.v2.client.algod.TealDisassemble; -import com.algorand.algosdk.v2.client.algod.TealDryrun; import com.algorand.algosdk.v2.client.algod.GetBlockTimeStampOffset; import com.algorand.algosdk.v2.client.algod.SetBlockTimeStampOffset; import com.algorand.algosdk.crypto.Address; @@ -342,9 +341,18 @@ public GetApplicationByID GetApplicationByID(Long applicationId) { } /** - * Given an application ID, return all Box names. No particular ordering is + * Given an application ID, return all box names. No particular ordering is * guaranteed. Request fails when client or server-side configured limits prevent - * returning all Box names. + * returning all box names. + * Pagination mode is enabled when any of the following parameters are provided: + * limit, next, prefix, include, or round. In pagination mode box values can be + * requested and results are returned in sorted order. + * To paginate: use the next-token from a previous response as the next parameter + * in the following request. Pin the round parameter to the round value from the + * first page's response to ensure consistent results across pages. The server + * enforces a per-response byte limit, so fewer results than limit may be returned + * even when more exist; the presence of next-token is the only reliable signal + * that more data is available. * /v2/applications/{application-id}/boxes */ public GetApplicationBoxes GetApplicationBoxes(Long applicationId) { @@ -416,16 +424,6 @@ public TealDisassemble TealDisassemble() { return new TealDisassemble((Client) this); } - /** - * Executes TEAL program(s) in context and returns debugging information about the - * execution. This endpoint is only enabled when a node's configuration file sets - * EnableDeveloperAPI to true. - * /v2/teal/dryrun - */ - public TealDryrun TealDryrun() { - return new TealDryrun((Client) this); - } - /** * Gets the current timestamp offset. * /v2/devmode/blocks/offset diff --git a/src/main/java/com/algorand/algosdk/v2/client/indexer/LookupAccountTransactions.java b/src/main/java/com/algorand/algosdk/v2/client/indexer/LookupAccountTransactions.java index d99ec5b91..222e9a568 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/indexer/LookupAccountTransactions.java +++ b/src/main/java/com/algorand/algosdk/v2/client/indexer/LookupAccountTransactions.java @@ -135,6 +135,7 @@ public LookupAccountTransactions round(Long round) { * sig - Standard * msig - MultiSig * lsig - LogicSig + * pqsig - Post-Quantum */ public LookupAccountTransactions sigType(Enums.SigType sigType) { addQuery("sig-type", String.valueOf(sigType)); diff --git a/src/main/java/com/algorand/algosdk/v2/client/indexer/LookupAssetTransactions.java b/src/main/java/com/algorand/algosdk/v2/client/indexer/LookupAssetTransactions.java index ede4367b1..13d0d1ee1 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/indexer/LookupAssetTransactions.java +++ b/src/main/java/com/algorand/algosdk/v2/client/indexer/LookupAssetTransactions.java @@ -153,6 +153,7 @@ public LookupAssetTransactions round(Long round) { * sig - Standard * msig - MultiSig * lsig - LogicSig + * pqsig - Post-Quantum */ public LookupAssetTransactions sigType(Enums.SigType sigType) { addQuery("sig-type", String.valueOf(sigType)); diff --git a/src/main/java/com/algorand/algosdk/v2/client/indexer/SearchForApplicationBoxes.java b/src/main/java/com/algorand/algosdk/v2/client/indexer/SearchForApplicationBoxes.java index 5cabe8a26..6d102771a 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/indexer/SearchForApplicationBoxes.java +++ b/src/main/java/com/algorand/algosdk/v2/client/indexer/SearchForApplicationBoxes.java @@ -1,11 +1,16 @@ package com.algorand.algosdk.v2.client.indexer; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + import com.algorand.algosdk.v2.client.common.Client; import com.algorand.algosdk.v2.client.common.HttpMethod; import com.algorand.algosdk.v2.client.common.Query; import com.algorand.algosdk.v2.client.common.QueryData; import com.algorand.algosdk.v2.client.common.Response; import com.algorand.algosdk.v2.client.model.BoxesResponse; +import com.algorand.algosdk.v2.client.model.Enums; /** @@ -25,6 +30,15 @@ public SearchForApplicationBoxes(Client client, Long applicationId) { this.applicationId = applicationId; } + /** + * Include additional items in the response. Use `values` to include box values. + * Multiple values can be comma-separated. + */ + public SearchForApplicationBoxes include(List include) { + addQuery("include", StringUtils.join(include, ",")); + return this; + } + /** * Maximum number of results to return. There could be additional pages even if the * limit is not reached. diff --git a/src/main/java/com/algorand/algosdk/v2/client/indexer/SearchForTransactions.java b/src/main/java/com/algorand/algosdk/v2/client/indexer/SearchForTransactions.java index 8f126f6a7..f746f0de4 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/indexer/SearchForTransactions.java +++ b/src/main/java/com/algorand/algosdk/v2/client/indexer/SearchForTransactions.java @@ -174,6 +174,7 @@ public SearchForTransactions round(Long round) { * sig - Standard * msig - MultiSig * lsig - LogicSig + * pqsig - Post-Quantum */ public SearchForTransactions sigType(Enums.SigType sigType) { addQuery("sig-type", String.valueOf(sigType)); diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/Account.java b/src/main/java/com/algorand/algosdk/v2/client/model/Account.java index d9bac5d29..88f54cd08 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/model/Account.java +++ b/src/main/java/com/algorand/algosdk/v2/client/model/Account.java @@ -188,6 +188,7 @@ public String authAddr() throws NoSuchAlgorithmException { * sig * msig * lsig + * pqsig * or null if unknown */ @JsonProperty("sig-type") diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/Block.java b/src/main/java/com/algorand/algosdk/v2/client/model/Block.java index 5db14d9ea..29256446d 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/model/Block.java +++ b/src/main/java/com/algorand/algosdk/v2/client/model/Block.java @@ -23,6 +23,13 @@ public class Block extends PathResponse { @JsonProperty("bonus") public Long bonus; + /** + * the fee required, beyond the minimum fee, for "normal" transactions in this + * block. + */ + @JsonProperty("congestion-tax") + public Long congestionTax; + /** * the sum of all fees paid by transactions in this block. */ @@ -47,6 +54,14 @@ public String genesisHash() { @JsonProperty("genesis-id") public String genesisId; + /** + * the degree to which this block is full, based on the number of bytes in the + * final block compared to the maximum allowed. Expressed as a fixed-point integer + * with 6 digits of precision, so 1,000,000 is a completely full block. + */ + @JsonProperty("load") + public Long load; + /** * Participation account data that needs to be checked/acted on by the network. */ @@ -218,9 +233,11 @@ public boolean equals(Object o) { Block other = (Block) o; if (!Objects.deepEquals(this.bonus, other.bonus)) return false; + if (!Objects.deepEquals(this.congestionTax, other.congestionTax)) return false; if (!Objects.deepEquals(this.feesCollected, other.feesCollected)) return false; if (!Objects.deepEquals(this.genesisHash, other.genesisHash)) return false; if (!Objects.deepEquals(this.genesisId, other.genesisId)) return false; + if (!Objects.deepEquals(this.load, other.load)) return false; if (!Objects.deepEquals(this.participationUpdates, other.participationUpdates)) return false; if (!Objects.deepEquals(this.previousBlockHash, other.previousBlockHash)) return false; if (!Objects.deepEquals(this.previousBlockHash512, other.previousBlockHash512)) return false; diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/BoxDescriptor.java b/src/main/java/com/algorand/algosdk/v2/client/model/BoxDescriptor.java index 7e12b7475..418e0187e 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/model/BoxDescriptor.java +++ b/src/main/java/com/algorand/algosdk/v2/client/model/BoxDescriptor.java @@ -7,7 +7,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** - * Box descriptor describes an app box without a value. + * Box descriptor describes an app box. */ public class BoxDescriptor extends PathResponse { @@ -23,6 +23,19 @@ public String name() { } public byte[] name; + /** + * Base64 encoded box value. Present only when the `values` query parameter is set + * to true. + */ + @JsonProperty("value") + public void value(String base64Encoded) { + this.value = Encoder.decodeFromBase64(base64Encoded); + } + public String value() { + return Encoder.encodeToBase64(this.value); + } + public byte[] value; + @Override public boolean equals(Object o) { @@ -31,6 +44,7 @@ public boolean equals(Object o) { BoxDescriptor other = (BoxDescriptor) o; if (!Objects.deepEquals(this.name, other.name)) return false; + if (!Objects.deepEquals(this.value, other.value)) return false; return true; } diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/BoxesResponse.java b/src/main/java/com/algorand/algosdk/v2/client/model/BoxesResponse.java index 7a9ea9af5..193fdfb2a 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/model/BoxesResponse.java +++ b/src/main/java/com/algorand/algosdk/v2/client/model/BoxesResponse.java @@ -28,6 +28,12 @@ public class BoxesResponse extends PathResponse { @JsonProperty("next-token") public String nextToken; + /** + * The round for which this information is relevant. + */ + @JsonProperty("round") + public Long round; + @Override public boolean equals(Object o) { @@ -38,6 +44,7 @@ public boolean equals(Object o) { if (!Objects.deepEquals(this.applicationId, other.applicationId)) return false; if (!Objects.deepEquals(this.boxes, other.boxes)) return false; if (!Objects.deepEquals(this.nextToken, other.nextToken)) return false; + if (!Objects.deepEquals(this.round, other.round)) return false; return true; } diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/DryrunRequest.java b/src/main/java/com/algorand/algosdk/v2/client/model/DryrunRequest.java deleted file mode 100644 index 5b320fe76..000000000 --- a/src/main/java/com/algorand/algosdk/v2/client/model/DryrunRequest.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.algorand.algosdk.v2.client.model; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import com.algorand.algosdk.transaction.SignedTransaction; -import com.algorand.algosdk.v2.client.common.PathResponse; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * Request data type for dryrun endpoint. Given the Transactions and simulated - * ledger state upload, run TEAL scripts and return debugging information. - */ -public class DryrunRequest extends PathResponse { - - @JsonProperty("accounts") - public List accounts = new ArrayList(); - - @JsonProperty("apps") - public List apps = new ArrayList(); - - /** - * LatestTimestamp is available to some TEAL scripts. Defaults to the latest - * confirmed timestamp this algod is attached to. - */ - @JsonProperty("latest-timestamp") - public Long latestTimestamp; - - /** - * ProtocolVersion specifies a specific version string to operate under, otherwise - * whatever the current protocol of the network this algod is running in. - */ - @JsonProperty("protocol-version") - public String protocolVersion; - - /** - * Round is available to some TEAL scripts. Defaults to the current round on the - * network this algod is attached to. - */ - @JsonProperty("round") - public java.math.BigInteger round; - - @JsonProperty("sources") - public List sources = new ArrayList(); - - @JsonProperty("txns") - public List txns = new ArrayList(); - - @Override - public boolean equals(Object o) { - - if (this == o) return true; - if (o == null) return false; - - DryrunRequest other = (DryrunRequest) o; - if (!Objects.deepEquals(this.accounts, other.accounts)) return false; - if (!Objects.deepEquals(this.apps, other.apps)) return false; - if (!Objects.deepEquals(this.latestTimestamp, other.latestTimestamp)) return false; - if (!Objects.deepEquals(this.protocolVersion, other.protocolVersion)) return false; - if (!Objects.deepEquals(this.round, other.round)) return false; - if (!Objects.deepEquals(this.sources, other.sources)) return false; - if (!Objects.deepEquals(this.txns, other.txns)) return false; - - return true; - } -} diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/DryrunResponse.java b/src/main/java/com/algorand/algosdk/v2/client/model/DryrunResponse.java deleted file mode 100644 index 038e81532..000000000 --- a/src/main/java/com/algorand/algosdk/v2/client/model/DryrunResponse.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.algorand.algosdk.v2.client.model; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import com.algorand.algosdk.v2.client.common.PathResponse; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * DryrunResponse contains per-txn debug information from a dryrun. - */ -public class DryrunResponse extends PathResponse { - - @JsonProperty("error") - public String error; - - /** - * Protocol version is the protocol version Dryrun was operated under. - */ - @JsonProperty("protocol-version") - public String protocolVersion; - - @JsonProperty("txns") - public List txns = new ArrayList(); - - @Override - public boolean equals(Object o) { - - if (this == o) return true; - if (o == null) return false; - - DryrunResponse other = (DryrunResponse) o; - if (!Objects.deepEquals(this.error, other.error)) return false; - if (!Objects.deepEquals(this.protocolVersion, other.protocolVersion)) return false; - if (!Objects.deepEquals(this.txns, other.txns)) return false; - - return true; - } -} diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/DryrunSource.java b/src/main/java/com/algorand/algosdk/v2/client/model/DryrunSource.java deleted file mode 100644 index 2cb2534c5..000000000 --- a/src/main/java/com/algorand/algosdk/v2/client/model/DryrunSource.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.algorand.algosdk.v2.client.model; - -import java.util.Objects; - -import com.algorand.algosdk.v2.client.common.PathResponse; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * DryrunSource is TEAL source text that gets uploaded, compiled, and inserted into - * transactions or application state. - */ -public class DryrunSource extends PathResponse { - - @JsonProperty("app-index") - public java.math.BigInteger appIndex; - - /** - * FieldName is what kind of sources this is. If lsig then it goes into the - * transactions[this.TxnIndex].LogicSig. If approv or clearp it goes into the - * Approval Program or Clear State Program of application[this.AppIndex]. - */ - @JsonProperty("field-name") - public String fieldName; - - @JsonProperty("source") - public String source; - - @JsonProperty("txn-index") - public Long txnIndex; - - @Override - public boolean equals(Object o) { - - if (this == o) return true; - if (o == null) return false; - - DryrunSource other = (DryrunSource) o; - if (!Objects.deepEquals(this.appIndex, other.appIndex)) return false; - if (!Objects.deepEquals(this.fieldName, other.fieldName)) return false; - if (!Objects.deepEquals(this.source, other.source)) return false; - if (!Objects.deepEquals(this.txnIndex, other.txnIndex)) return false; - - return true; - } -} diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/DryrunState.java b/src/main/java/com/algorand/algosdk/v2/client/model/DryrunState.java deleted file mode 100644 index 14144befa..000000000 --- a/src/main/java/com/algorand/algosdk/v2/client/model/DryrunState.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.algorand.algosdk.v2.client.model; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import com.algorand.algosdk.v2.client.common.PathResponse; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * Stores the TEAL eval step data - */ -public class DryrunState extends PathResponse { - - /** - * Evaluation error if any - */ - @JsonProperty("error") - public String error; - - /** - * Line number - */ - @JsonProperty("line") - public Long line; - - /** - * Program counter - */ - @JsonProperty("pc") - public Long pc; - - @JsonProperty("scratch") - public List scratch = new ArrayList(); - - @JsonProperty("stack") - public List stack = new ArrayList(); - - @Override - public boolean equals(Object o) { - - if (this == o) return true; - if (o == null) return false; - - DryrunState other = (DryrunState) o; - if (!Objects.deepEquals(this.error, other.error)) return false; - if (!Objects.deepEquals(this.line, other.line)) return false; - if (!Objects.deepEquals(this.pc, other.pc)) return false; - if (!Objects.deepEquals(this.scratch, other.scratch)) return false; - if (!Objects.deepEquals(this.stack, other.stack)) return false; - - return true; - } -} diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/DryrunTxnResult.java b/src/main/java/com/algorand/algosdk/v2/client/model/DryrunTxnResult.java deleted file mode 100644 index a5f645518..000000000 --- a/src/main/java/com/algorand/algosdk/v2/client/model/DryrunTxnResult.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.algorand.algosdk.v2.client.model; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import com.algorand.algosdk.util.Encoder; -import com.algorand.algosdk.v2.client.common.PathResponse; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * DryrunTxnResult contains any LogicSig or ApplicationCall program debug - * information and state updates from a dryrun. - */ -public class DryrunTxnResult extends PathResponse { - - @JsonProperty("app-call-messages") - public List appCallMessages = new ArrayList(); - - @JsonProperty("app-call-trace") - public List appCallTrace = new ArrayList(); - - /** - * Budget added during execution of app call transaction. - */ - @JsonProperty("budget-added") - public Long budgetAdded; - - /** - * Budget consumed during execution of app call transaction. - */ - @JsonProperty("budget-consumed") - public Long budgetConsumed; - - /** - * Disassembled program line by line. - */ - @JsonProperty("disassembly") - public List disassembly = new ArrayList(); - - /** - * Application state delta. - */ - @JsonProperty("global-delta") - public List globalDelta = new ArrayList(); - - @JsonProperty("local-deltas") - public List localDeltas = new ArrayList(); - - /** - * Disassembled lsig program line by line. - */ - @JsonProperty("logic-sig-disassembly") - public List logicSigDisassembly = new ArrayList(); - - @JsonProperty("logic-sig-messages") - public List logicSigMessages = new ArrayList(); - - @JsonProperty("logic-sig-trace") - public List logicSigTrace = new ArrayList(); - - @JsonProperty("logs") - public List logs = new ArrayList(); - @JsonIgnore - public void logs(List base64Encoded) { - this.logs = new ArrayList(); - for (String val : base64Encoded) { - this.logs.add(Encoder.decodeFromBase64(val)); - } - } - @JsonIgnore - public List logs() { - ArrayList ret = new ArrayList(); - for (byte[] val : this.logs) { - ret.add(Encoder.encodeToBase64(val)); - } - return ret; - } - - @Override - public boolean equals(Object o) { - - if (this == o) return true; - if (o == null) return false; - - DryrunTxnResult other = (DryrunTxnResult) o; - if (!Objects.deepEquals(this.appCallMessages, other.appCallMessages)) return false; - if (!Objects.deepEquals(this.appCallTrace, other.appCallTrace)) return false; - if (!Objects.deepEquals(this.budgetAdded, other.budgetAdded)) return false; - if (!Objects.deepEquals(this.budgetConsumed, other.budgetConsumed)) return false; - if (!Objects.deepEquals(this.disassembly, other.disassembly)) return false; - if (!Objects.deepEquals(this.globalDelta, other.globalDelta)) return false; - if (!Objects.deepEquals(this.localDeltas, other.localDeltas)) return false; - if (!Objects.deepEquals(this.logicSigDisassembly, other.logicSigDisassembly)) return false; - if (!Objects.deepEquals(this.logicSigMessages, other.logicSigMessages)) return false; - if (!Objects.deepEquals(this.logicSigTrace, other.logicSigTrace)) return false; - if (!Objects.deepEquals(this.logs, other.logs)) return false; - - return true; - } -} diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/Enums.java b/src/main/java/com/algorand/algosdk/v2/client/model/Enums.java index bf8b34749..190e57587 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/model/Enums.java +++ b/src/main/java/com/algorand/algosdk/v2/client/model/Enums.java @@ -36,6 +36,33 @@ public static AddressRole forValue(String value) { } + public enum ConnectionType { + @JsonProperty("inbound") INBOUND("inbound"), + @JsonProperty("outbound") OUTBOUND("outbound"), + @JsonProperty("") UNKNOWN(""); + + final String serializedName; + ConnectionType(String name) { + this.serializedName = name; + } + + @Override + public String toString() { + return this.serializedName; + } + + @JsonCreator + public static ConnectionType forValue(String value) { + for (ConnectionType t : values()) { + if (t.serializedName.equalsIgnoreCase(value)) { + return t; + } + } + return UNKNOWN; + } + + } + /** * Exclude additional items such as asset holdings, application local data stored * for this account, asset parameters created by this account, and application @@ -106,8 +133,13 @@ public static Hashtype forValue(String value) { } + /** + * Include additional items in the response. Use `values` to include box values. + * Multiple values can be comma-separated. + */ public enum Include { @JsonProperty("params") PARAMS("params"), + @JsonProperty("values") VALUES("values"), @JsonProperty("") UNKNOWN(""); final String serializedName; @@ -132,6 +164,33 @@ public static Include forValue(String value) { } + public enum NetworkType { + @JsonProperty("p2p") P2P("p2p"), + @JsonProperty("ws") WS("ws"), + @JsonProperty("") UNKNOWN(""); + + final String serializedName; + NetworkType(String name) { + this.serializedName = name; + } + + @Override + public String toString() { + return this.serializedName; + } + + @JsonCreator + public static NetworkType forValue(String value) { + for (NetworkType t : values()) { + if (t.serializedName.equalsIgnoreCase(value)) { + return t; + } + } + return UNKNOWN; + } + + } + /** * (apan) defines the what additional actions occur with the transaction. * Valid types: @@ -179,11 +238,13 @@ public static OnCompletion forValue(String value) { * sig - Standard * msig - MultiSig * lsig - LogicSig + * pqsig - Post-Quantum */ public enum SigType { @JsonProperty("sig") SIG("sig"), @JsonProperty("msig") MSIG("msig"), @JsonProperty("lsig") LSIG("lsig"), + @JsonProperty("pqsig") PQSIG("pqsig"), @JsonProperty("") UNKNOWN(""); final String serializedName; diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/GetPeersResponse.java b/src/main/java/com/algorand/algosdk/v2/client/model/GetPeersResponse.java new file mode 100644 index 000000000..8ef87e4db --- /dev/null +++ b/src/main/java/com/algorand/algosdk/v2/client/model/GetPeersResponse.java @@ -0,0 +1,29 @@ +package com.algorand.algosdk.v2.client.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import com.algorand.algosdk.v2.client.common.PathResponse; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Response containing the network peers of the node + */ +public class GetPeersResponse extends PathResponse { + + @JsonProperty("Peers") + public List peers = new ArrayList(); + + @Override + public boolean equals(Object o) { + + if (this == o) return true; + if (o == null) return false; + + GetPeersResponse other = (GetPeersResponse) o; + if (!Objects.deepEquals(this.peers, other.peers)) return false; + + return true; + } +} diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/PeerStatus.java b/src/main/java/com/algorand/algosdk/v2/client/model/PeerStatus.java new file mode 100644 index 000000000..a3f31fd7d --- /dev/null +++ b/src/main/java/com/algorand/algosdk/v2/client/model/PeerStatus.java @@ -0,0 +1,44 @@ +package com.algorand.algosdk.v2.client.model; + +import java.util.Objects; + +import com.algorand.algosdk.v2.client.common.PathResponse; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * The status of a connected peer in the P2P network + */ +public class PeerStatus extends PathResponse { + + /** + * Connection type + */ + @JsonProperty("connection-type") + public Enums.ConnectionType connectionType; + + /** + * Network address of the peer + */ + @JsonProperty("network-address") + public String networkAddress; + + /** + * Network type + */ + @JsonProperty("network-type") + public Enums.NetworkType networkType; + + @Override + public boolean equals(Object o) { + + if (this == o) return true; + if (o == null) return false; + + PeerStatus other = (PeerStatus) o; + if (!Objects.deepEquals(this.connectionType, other.connectionType)) return false; + if (!Objects.deepEquals(this.networkAddress, other.networkAddress)) return false; + if (!Objects.deepEquals(this.networkType, other.networkType)) return false; + + return true; + } +} diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTransactionGroupResult.java b/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTransactionGroupResult.java index 6045d1bab..07130c9eb 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTransactionGroupResult.java +++ b/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTransactionGroupResult.java @@ -40,6 +40,20 @@ public class SimulateTransactionGroupResult extends PathResponse { @JsonProperty("failure-message") public String failureMessage; + /** + * Total fees paid by the transaction group and all of its descendant inner + * transaction groups. + */ + @JsonProperty("group-fees-paid") + public Long groupFeesPaid; + + /** + * Fee usage for the transaction group, including all descendant inner + * transactions, in millionths of a basic transaction fee unit. + */ + @JsonProperty("group-usage") + public Long groupUsage; + /** * Simulation result for individual transactions */ @@ -71,6 +85,8 @@ public boolean equals(Object o) { if (!Objects.deepEquals(this.appBudgetConsumed, other.appBudgetConsumed)) return false; if (!Objects.deepEquals(this.failedAt, other.failedAt)) return false; if (!Objects.deepEquals(this.failureMessage, other.failureMessage)) return false; + if (!Objects.deepEquals(this.groupFeesPaid, other.groupFeesPaid)) return false; + if (!Objects.deepEquals(this.groupUsage, other.groupUsage)) return false; if (!Objects.deepEquals(this.txnResults, other.txnResults)) return false; if (!Objects.deepEquals(this.unnamedResourcesAccessed, other.unnamedResourcesAccessed)) return false; diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTransactionResult.java b/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTransactionResult.java index ac906ba17..e4bfc229c 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTransactionResult.java +++ b/src/main/java/com/algorand/algosdk/v2/client/model/SimulateTransactionResult.java @@ -26,6 +26,13 @@ public class SimulateTransactionResult extends PathResponse { @JsonProperty("exec-trace") public SimulationTransactionExecTrace execTrace; + /** + * Total fees paid by this transaction and all of its descendant inner + * transactions. + */ + @JsonProperty("fees-paid") + public Long feesPaid; + /** * The account that needed to sign this transaction when no signature was provided * and the provided signer was incorrect. @@ -80,6 +87,7 @@ public boolean equals(Object o) { SimulateTransactionResult other = (SimulateTransactionResult) o; if (!Objects.deepEquals(this.appBudgetConsumed, other.appBudgetConsumed)) return false; if (!Objects.deepEquals(this.execTrace, other.execTrace)) return false; + if (!Objects.deepEquals(this.feesPaid, other.feesPaid)) return false; if (!Objects.deepEquals(this.fixedSigner, other.fixedSigner)) return false; if (!Objects.deepEquals(this.logicSigBudgetConsumed, other.logicSigBudgetConsumed)) return false; if (!Objects.deepEquals(this.txnResult, other.txnResult)) return false; diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/TransactionHeartbeat.java b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionHeartbeat.java index dff70bad2..1c13a2fa9 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/model/TransactionHeartbeat.java +++ b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionHeartbeat.java @@ -19,6 +19,14 @@ public class TransactionHeartbeat extends PathResponse { @JsonProperty("hb-address") public String hbAddress; + /** + * (hbc) HbChallengeDiscount requests the challenge fee discount, reducing the + * required fee by one min fee. It is a request, not an assertion: it is granted + * only if HbAddress is actually under challenge. + */ + @JsonProperty("hb-challenge-discount") + public Boolean hbChallengeDiscount; + /** * (hbkd) HbKeyDilution must match HbAddress account's current KeyDilution. */ @@ -65,6 +73,7 @@ public boolean equals(Object o) { TransactionHeartbeat other = (TransactionHeartbeat) o; if (!Objects.deepEquals(this.hbAddress, other.hbAddress)) return false; + if (!Objects.deepEquals(this.hbChallengeDiscount, other.hbChallengeDiscount)) return false; if (!Objects.deepEquals(this.hbKeyDilution, other.hbKeyDilution)) return false; if (!Objects.deepEquals(this.hbProof, other.hbProof)) return false; if (!Objects.deepEquals(this.hbSeed, other.hbSeed)) return false; diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/TransactionParametersResponse.java b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionParametersResponse.java index 12b366e94..d807b189d 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/model/TransactionParametersResponse.java +++ b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionParametersResponse.java @@ -53,8 +53,8 @@ public String genesisHash() { public Long lastRound; /** - * The minimum transaction fee (not per byte) required for the - * txn to validate for the current network protocol. + * The minimum transaction fee (not per byte) required for the txn to validate for + * the current network protocol. */ @JsonProperty("min-fee") public Long minFee; diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/TransactionSignature.java b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionSignature.java index 5f4407830..3b1eada55 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/model/TransactionSignature.java +++ b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionSignature.java @@ -28,6 +28,14 @@ public class TransactionSignature extends PathResponse { @JsonProperty("multisig") public TransactionSignatureMultisig multisig; + /** + * structure holding a post-quantum signature. + * Definition: + * data/transactions/pqsig.go : PQSig + */ + @JsonProperty("pqsig") + public TransactionSignaturePQsig pqsig; + /** * (sig) Standard ed25519 signature. */ @@ -49,6 +57,7 @@ public boolean equals(Object o) { TransactionSignature other = (TransactionSignature) o; if (!Objects.deepEquals(this.logicsig, other.logicsig)) return false; if (!Objects.deepEquals(this.multisig, other.multisig)) return false; + if (!Objects.deepEquals(this.pqsig, other.pqsig)) return false; if (!Objects.deepEquals(this.sig, other.sig)) return false; return true; diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/TransactionSignatureLogicsig.java b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionSignatureLogicsig.java index 1bdb905f2..0b4597206 100644 --- a/src/main/java/com/algorand/algosdk/v2/client/model/TransactionSignatureLogicsig.java +++ b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionSignatureLogicsig.java @@ -66,6 +66,14 @@ public String logic() { @JsonProperty("multisig-signature") public TransactionSignatureMultisig multisigSignature; + /** + * structure holding a post-quantum signature. + * Definition: + * data/transactions/pqsig.go : PQSig + */ + @JsonProperty("pqsig") + public TransactionSignaturePQsig pqsig; + /** * (sig) ed25519 signature. */ @@ -89,6 +97,7 @@ public boolean equals(Object o) { if (!Objects.deepEquals(this.logic, other.logic)) return false; if (!Objects.deepEquals(this.logicMultisigSignature, other.logicMultisigSignature)) return false; if (!Objects.deepEquals(this.multisigSignature, other.multisigSignature)) return false; + if (!Objects.deepEquals(this.pqsig, other.pqsig)) return false; if (!Objects.deepEquals(this.signature, other.signature)) return false; return true; diff --git a/src/main/java/com/algorand/algosdk/v2/client/model/TransactionSignaturePQsig.java b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionSignaturePQsig.java new file mode 100644 index 000000000..876cfe206 --- /dev/null +++ b/src/main/java/com/algorand/algosdk/v2/client/model/TransactionSignaturePQsig.java @@ -0,0 +1,67 @@ +package com.algorand.algosdk.v2.client.model; + +import java.util.Objects; + +import com.algorand.algosdk.util.Encoder; +import com.algorand.algosdk.v2.client.common.PathResponse; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * structure holding a post-quantum signature. + * Definition: + * data/transactions/pqsig.go : PQSig + */ +public class TransactionSignaturePQsig extends PathResponse { + + /** + * (pk) + */ + @JsonProperty("public-key") + public void publicKey(String base64Encoded) { + this.publicKey = Encoder.decodeFromBase64(base64Encoded); + } + public String publicKey() { + return Encoder.encodeToBase64(this.publicKey); + } + public byte[] publicKey; + + /** + * (slt) a single byte, added to ensure the hashed address is not an Ed25519 curve + * point + */ + @JsonProperty("salt") + public Long salt; + + /** + * (sch) identifies the internal signature scheme. + */ + @JsonProperty("scheme") + public String scheme; + + /** + * (sig) + */ + @JsonProperty("signature") + public void signature(String base64Encoded) { + this.signature = Encoder.decodeFromBase64(base64Encoded); + } + public String signature() { + return Encoder.encodeToBase64(this.signature); + } + public byte[] signature; + + @Override + public boolean equals(Object o) { + + if (this == o) return true; + if (o == null) return false; + + TransactionSignaturePQsig other = (TransactionSignaturePQsig) o; + if (!Objects.deepEquals(this.publicKey, other.publicKey)) return false; + if (!Objects.deepEquals(this.salt, other.salt)) return false; + if (!Objects.deepEquals(this.scheme, other.scheme)) return false; + if (!Objects.deepEquals(this.signature, other.signature)) return false; + + return true; + } +} diff --git a/src/test/integration.tags b/src/test/integration.tags index f8b49f9fc..ab39f98ce 100644 --- a/src/test/integration.tags +++ b/src/test/integration.tags @@ -8,7 +8,6 @@ @compile @compile.disassemble @compile.sourcemap -@dryrun @kmd @rekey_v1 @send diff --git a/src/test/java/com/algorand/algosdk/integration/Stepdefs.java b/src/test/java/com/algorand/algosdk/integration/Stepdefs.java index 95548d66c..39c457011 100644 --- a/src/test/java/com/algorand/algosdk/integration/Stepdefs.java +++ b/src/test/java/com/algorand/algosdk/integration/Stepdefs.java @@ -103,9 +103,8 @@ public class Stepdefs { com.algorand.algosdk.transaction.AssetParams expectedParams = null; Asset queriedParams = new Asset(); - /* Compile / Dryrun */ + /* Compile */ Response compileResponse; - Response dryrunResponse; protected Address getAddress(int i) { if (addresses == null) { @@ -1107,62 +1106,6 @@ public void it_is_compiled_with(Integer status, String result, String hash) { } } - @When("I dryrun a {string} program {string}") - public void i_dryrun_a_program(String kind, String path) throws Exception { - byte[] data = loadResource(path); - List sources = new ArrayList(); - List stxns = new ArrayList(); - Account account = new Account(); - Address pk = account.getAddress(); - Digest gh = new Digest(Encoder.decodeFromBase64("ZIkPs8pTDxbRJsFB1yJ7gvnpDu0Q85FRkl2NCkEAQLU=")); - Transaction txn = Transaction.PaymentTransactionBuilder() - .sender(pk) - .fee(1000) - .firstValid(1) - .lastValid(100) - .amount(1000) - .genesisHash(gh) - .receiver(pk) - .build(); - - if (kind.equals("compiled")) { - LogicsigSignature lsig = new LogicsigSignature(data); - SignedTransaction stxn = new SignedTransaction(txn, lsig); - stxns.add(stxn); - } else if (kind.equals("source")) { - DryrunSource drs = new DryrunSource(); - drs.fieldName = "lsig"; - drs.source = new String(data); - drs.txnIndex = 0L; - sources.add(drs); - SignedTransaction stxn = new SignedTransaction(txn, new Signature()); - stxns.add(stxn); - } else { - fail("kind " + kind + " not in (compiled, source)"); - } - - DryrunRequest dr = new DryrunRequest(); - dr.txns = stxns; - dr.sources = sources; - dryrunResponse = aclv2.TealDryrun().request(dr).execute(); - } - - @When("I get execution result {string}") - public void i_get_execution_result(String result) { - DryrunResponse ddr = dryrunResponse.body(); - assertThat(ddr).isNotNull(); - assertThat(ddr.txns).isNotNull(); - assertThat(ddr.txns.size()).isGreaterThan(0); - List msgs = new ArrayList(); - if (ddr.txns.get(0).appCallMessages.size() > 0) { - msgs = ddr.txns.get(0).appCallMessages; - } else if (ddr.txns.get(0).logicSigMessages.size() > 0) { - msgs = ddr.txns.get(0).logicSigMessages; - } - assertThat(msgs.size()).isGreaterThan(0); - assertThat(msgs.get(msgs.size() - 1)).isEqualTo(result); - } - @When("I compile a teal program {string} with mapping enabled") public void i_compile_a_teal_program_with_mapping_enabled(String tealPath) throws Exception { byte[] tealProgram = ResourceUtils.loadResource(tealPath); diff --git a/src/test/java/com/algorand/algosdk/unit/AlgodResponses.java b/src/test/java/com/algorand/algosdk/unit/AlgodResponses.java index 0583f1f84..45ff09a51 100644 --- a/src/test/java/com/algorand/algosdk/unit/AlgodResponses.java +++ b/src/test/java/com/algorand/algosdk/unit/AlgodResponses.java @@ -26,7 +26,6 @@ public class AlgodResponses { Response postTransactionsResponse; Response supplyResponse; Response transactionParametersResponse; - Response tealDryrunResponse; public AlgodResponses(ResponsesShared shared) { this.shared = shared; @@ -93,12 +92,6 @@ public void we_make_any_Suggested_Transaction_Parameters_call() throws Exception transactionParametersResponse = client.TransactionParams().execute(); } - @When("we make any Dryrun call") - public void we_make_any_Dryrun_call() throws Exception { - ClientMocker.infect(client); - tealDryrunResponse = client.TealDryrun().request(new DryrunRequest()).execute(); - } - @Then("the parsed Pending Transaction Information response should have sender {string}") public void the_parsed_Pending_Transaction_Information_response_should_have_sender(String string) throws IOException { verifyResponse(pendingTransactionResponse, shared.bodyFile); @@ -159,11 +152,4 @@ public void the_parsed_Suggested_Transaction_Parameters_response_should_have_fir public void the_parsed_Send_Raw_Transaction_response_should_have_txid(String txid) throws IOException { verifyResponse(postTransactionsResponse, shared.bodyFile); } - - @Then("the parsed Dryrun Response should have global delta {string} with {int}") - public void the_parsed_Dryrun_Response_should_have(String key, int action) throws Exception { - verifyResponse(tealDryrunResponse, shared.bodyFile); - assertThat(tealDryrunResponse.body().txns.get(0).globalDelta.get(0).key).isEqualTo(key); - assertThat(tealDryrunResponse.body().txns.get(0).globalDelta.get(0).value.action).isEqualTo(action); - } } diff --git a/src/test/java/com/algorand/algosdk/unit/ResponsesShared.java b/src/test/java/com/algorand/algosdk/unit/ResponsesShared.java index 1ef280077..00b1fdf89 100644 --- a/src/test/java/com/algorand/algosdk/unit/ResponsesShared.java +++ b/src/test/java/com/algorand/algosdk/unit/ResponsesShared.java @@ -2,14 +2,9 @@ import com.algorand.algosdk.crypto.Address; import com.algorand.algosdk.unit.utils.ClientMocker; -import com.algorand.algosdk.util.Encoder; -import com.algorand.algosdk.util.ResourceUtils; -import com.algorand.algosdk.v2.client.Utils; import com.algorand.algosdk.v2.client.common.AlgodClient; import com.algorand.algosdk.v2.client.common.IndexerClient; import com.algorand.algosdk.v2.client.common.Response; -import com.algorand.algosdk.v2.client.model.DryrunResponse; -import com.algorand.algosdk.v2.client.model.DryrunTxnResult; import com.algorand.algosdk.v2.client.model.StateProof; import com.google.common.io.Files; import io.cucumber.java.en.Given; @@ -19,7 +14,6 @@ import java.io.File; import java.io.IOException; -import java.nio.charset.StandardCharsets; import static com.algorand.algosdk.unit.utils.TestingUtils.verifyResponse; import static org.assertj.core.api.Assertions.assertThat; @@ -28,7 +22,6 @@ public class ResponsesShared { public File bodyFile; @SuppressWarnings("rawtypes") public Response response; - public DryrunTxnResult dryrunTxnResult; public AlgodClient algod = new AlgodClient("localhost", 123, ""); public IndexerClient indexer = new IndexerClient("localhost", 123); @@ -165,9 +158,6 @@ public void we_make_any_call_to(String client, String endpoint) throws Exception case "GetPendingTransactionsByAddress": response = algod.GetPendingTransactionsByAddress(new Address()).execute(); break; - case "DryRun": - response = algod.TealDryrun().execute(); - break; case "Proof": case "GetTransactionProof": response = algod.GetTransactionProof(0L, "").execute(); @@ -230,29 +220,4 @@ public void we_make_any_call_to(String client, String endpoint) throws Exception public void the_parsed_response_should_equal() throws IOException { verifyResponse(response, bodyFile); } - - @Given("a dryrun response file {string} and a transaction at index {string}") - public void a_dryrun_response_file_and_a_transaction_at_index(String path, String strIdx) { - byte[] b = ResourceUtils.loadResource(path); - String str_resource = new String(b, StandardCharsets.UTF_8); - try{ - DryrunResponse drr = Encoder.decodeFromJson(str_resource, DryrunResponse.class); - int idx = Integer.parseInt(strIdx); - this.dryrunTxnResult = drr.txns.get(idx); - }catch(Exception e){ - assertThat(e).isNull(); - } - } - - @Then("calling app trace produces {string}") - public void calling_app_trace_produces(String path) { - byte[] b = ResourceUtils.loadResource(path); - String str_resource = new String(b, StandardCharsets.UTF_8); - Utils.StackPrinterConfig spc = new Utils.StackPrinterConfig(); - spc.maxValueWidth = 30; - spc.topOfStackFirst = false; - - String trace = Utils.appTrace(this.dryrunTxnResult, spc); - assertThat(str_resource).isEqualTo(trace); - } } diff --git a/src/test/unit.tags b/src/test/unit.tags index c0862a0a2..8235507b7 100644 --- a/src/test/unit.tags +++ b/src/test/unit.tags @@ -10,8 +10,6 @@ @unit.atomic_transaction_composer @unit.blocksummary @unit.blocktxids -@unit.dryrun -@unit.dryrun.trace.application @unit.feetest @unit.indexer @unit.indexer.blockheaders