ci: remove generated directory to reclaim disk space
fb53141e
trusty
1/7 ++ 1 --
Commits and releases over time
No repositories match that filter.
Drops the LogicSig program length check. Consensus v42 governs transaction size through fees rather than hard caps, so a hardcoded byte limit in client-side validation can reject a transaction the network would accept. A LogicSig carrying the legacy msig field now fails validation, since consensus v41 rejects it. Encoding and decoding are untouched, so pre-v41 transactions still round-trip. Access list indices are bounds-checked and must name the right kind of entry: a holding's asset index resolves to an Asset, a locals' app index to an App. Index 0 stays valid — it means the sender, or the app being called.
Consensus v42 governs transaction size through fees rather than hard caps, so a hardcoded byte limit in client-side validation can reject a transaction the network would accept. The empty-program and one-of-delegation checks stay, since those are structural rather than protocol limits.
Consensus v41 replaced the separate account, app, asset and box reference arrays on an app call with a single access list under the al tag, doubling the combined limit to 16 entries. ResourceRef is modelled as a struct with optional fields rather than an enum, matching go-algorand. An entry names at most one resource; an entry naming none is valid and bumps the box read/write quota, so is_empty is a real state rather than an error. Validation rejects entries naming more than one resource, rejects combining the access list with the legacy arrays, and caps the list at 16. The b slot reuses BoxReference, whose wire shape is identical, but its index means a position in the access list rather than an app id. The custom app call serializer rewrites legacy box references from app ids to positional indices, and must not touch access entries — a test pins that, since the failure would be a silent corruption rather than an error.
A logic signature authorizes a transaction with a program instead of a key. The program either owns its own account, whose address is the hash of the program, or is delegated by an account that signs it and spends from its own balance. SignedTransaction gains an lsig field, so a logicsig-signed transaction now survives a decode and re-encode instead of silently losing its authorization. Delegation targets lmsig. Consensus v41 rejects the legacy msig field on a LogicSig, because it hashed the bare program under the same domain separator a single-key delegation uses, letting a member's subsignature be lifted out and replayed as their own personal delegation. lmsig binds the multisig account address into the signed bytes. The msig field is kept so historical transactions decode, but nothing produces it. The block template declared its own opaque lsig field beside the flattened SignedTransaction, which would have shadowed the real one. Removed there and added to both generator constructors; algod_client/tests/models.rs pins that a logic signature reaches the flattened type, and lives outside src/ so it survives regeneration. The escrow address test uses the known program and address pair from the js-algorand-sdk suite rather than a locally computed value.
An all-zero signature is the absent signature on the wire — go-algorand drops it via MsgIsZero(), and js-algorand-sdk treats an all-zero fixed-length array as a default value and skips it. We were writing the 64 zero bytes, producing a blob no other implementation sends and inflating estimate_size along with any fee derived from it. The transaction id is unaffected, since it hashes the transaction rather than the envelope. The skip predicate now covers absent-or-all-zero, applied to the transaction signature and to multisig subsignatures, where a participant who has not signed yet would otherwise leave a zero-filled placeholder on the wire. Test scaffolds that used a zero signature as a stand-in were exercising nothing once it stopped being encoded, so they now use a non-zero placeholder — same encoded length, so the length assertions still hold.
Co-authored-by: David Rojas <lempira@users.noreply.github.com>
Adds a Simulate Tests group to the existing Composer suite — a new group rather than a new suite, so the generated stubs land in test_composer.py instead of creating a second file. Eight tests covering the request builders, the option merge rules, and the response mapper, including that a failing group is reported as data rather than raised. msgpack joins the Python test dependencies: the response-mapping tests need to construct an algod response, and nothing in the existing bindings can do that. Note that encoded transactions carry the "TX" domain-separator prefix, so unpacking one in Python means dropping the first two bytes. Three guards in sanity.sh protect properties that are otherwise invisible until something breaks far away: algod_client/ffi_uniffi must stay off, since Cargo unifies features workspace-wide and enabling it flips a type inside the simulate models for every consumer; algokit_composer's dependency tree must stay free of uniffi and the wasm-hostile getrandom 0.2; and the composer must keep compiling to wasm32, which no CI job currently checks.
Mirrors the simulate types and exposes three functions to the language bindings: build a request from unsigned or signed transactions, and map algod's reply onto a structured result. Every export is sync and performs no I/O. The calling language holds its own async context and HTTP stack and does the send in between, matching the convention the other _ffi crates follow for Swift 6. An earlier attempt to export the async round trip worked in Python but broke the Swift build: uniffi emits a second module for the HttpClient argument, and build_pkgs copies only one generated .swift per crate, so it never reaches Package.swift. Blocking on the network future instead is not an option either — it would deadlock against a foreign-supplied client and stall the event loop on wasm32. Rust callers keep the round trip via algokit_composer::simulate. Transactions and the algod response cross as msgpack bytes rather than mirrored structs. SimulateResponse pulls in roughly forty generated types that churn on every client regeneration, so mirroring them would guarantee drift; the curated projection plus the raw blob is lossless. Includes the regenerated Swift bindings, verified with swift build.
Simulate is a dry run: algod evaluates a transaction group exactly as it would on-chain and reports what would happen, without committing anything. It is the supported replacement for the dryrun endpoint, which go-algorand removed in v5.0.0. The module is split so only one step needs a network. Building a request from composed transactions and projecting algod's reply into a result are pure functions callers can use with their own HTTP stack; simulate(), simulate_unsigned() and simulate_signed() do the round trip over a transport the caller injects. Nothing is retained between calls, so the composer stays free of Rust-owned connection state and keeps compiling to wasm32. Two details worth calling out. Unsigned entries carry no sig key at all rather than a zero-filled one; the misleadingly named EMPTY_SIGNATURE constant is a test fixture and would emit 64 zero bytes no other SDK sends. And a failing simulation is returned as data, not an error, so the budgets and traces explaining it survive alongside the message; SimulateResult::into_result() opts into turning a failing group into an Err. Covered by 20 offline tests, including a stub transport that exercises the full async path with no node, plus four localnet tests behind #[ignore].