Skip to content

Commit

Permalink
cleanup, remove updateTimeout workaround, dont rebuild sorobandata
Browse files Browse the repository at this point in the history
  • Loading branch information
BlaineHeffron committed Jun 5, 2024
1 parent f7672ef commit ae4db84
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 46 deletions.
44 changes: 16 additions & 28 deletions src/contract/assembled_transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ export class AssembledTransaction<T> {
*/
static Errors = {
ExpiredState: class ExpiredStateError extends Error { },
RestoreFailure: class RestoreFailureError extends Error { },
RestorationFailure: class RestoreFailureError extends Error { },
NeedsMoreSignatures: class NeedsMoreSignaturesError extends Error { },
NoSignatureNeeded: class NoSignatureNeededError extends Error { },
NoUnsignedNonInvokerAuthEntries: class NoUnsignedNonInvokerAuthEntriesError extends Error { },
Expand All @@ -329,8 +329,8 @@ export class AssembledTransaction<T> {
method: this.options.method,
tx: this.built?.toXDR(),
simulationResult: {
auth: this.simulationData.result.auth.map((a) => a.toXDR("base64")),
retval: this.simulationData.result.retval.toXDR("base64"),
auth: this.simulationData.result?.auth.map((a) => a.toXDR("base64")),
retval: this.simulationData.result?.retval.toXDR("base64"),
},
simulationTransactionData:
this.simulationData.transactionData.toXDR("base64"),
Expand Down Expand Up @@ -374,8 +374,6 @@ export class AssembledTransaction<T> {
});
}



/**
* Construct a new AssembledTransaction. This is the only way to create a new
* AssembledTransaction; the main constructor is private.
Expand Down Expand Up @@ -472,7 +470,7 @@ export class AssembledTransaction<T> {
await this.simulate();
return this;
}
throw new AssembledTransaction.Errors.RestoreFailure(
throw new AssembledTransaction.Errors.RestorationFailure(
`Automatic restore failed! You set 'restore: true' but the attempted restore did not work. Result:\n${JSON.stringify(result)}`
);
}
Expand All @@ -488,7 +486,7 @@ export class AssembledTransaction<T> {
};

get simulationData(): {
result: Api.SimulateHostFunctionResult;
result?: Api.SimulateHostFunctionResult;
transactionData: xdr.SorobanTransactionData;
} {
if (this.simulationResult && this.simulationTransactionData) {
Expand All @@ -515,15 +513,15 @@ export class AssembledTransaction<T> {
);
}

if (!simulation.result) {
/*if (!simulation.result) {
throw new Error(
`Expected an invocation simulation, but got no 'result' field. Simulation: ${JSON.stringify(
simulation,
null,
2,
)}`,
);
}
}*/

// add to object for serialization & deserialization
this.simulationResult = simulation.result;
Expand All @@ -537,7 +535,10 @@ export class AssembledTransaction<T> {

get result(): T {
try {
return this.options.parseResultXdr(this.simulationData.result.retval);
if(!this.simulationData.result){
throw new Error("No simulation result!");
}
return this.options.parseResultXdr(this.simulationData.result?.retval);
} catch (e) {
if (!implementsToString(e)) throw e;
const err = this.parseError(e.toString());
Expand Down Expand Up @@ -566,7 +567,6 @@ export class AssembledTransaction<T> {
signAndSend = async ({
force = false,
signTransaction = this.options.signTransaction,
updateTimeout = true,
}: {
/**
* If `true`, sign and send the transaction even if it is a read call
Expand All @@ -576,11 +576,6 @@ export class AssembledTransaction<T> {
* You must provide this here if you did not provide one before
*/
signTransaction?: ClientOptions["signTransaction"];
/**
* Whether or not to update the timeout value before signing
* and sending the transaction
*/
updateTimeout?: boolean;
} = {}): Promise<SentTransaction<T>> => {
if (!this.built) {
throw new Error("Transaction has not yet been simulated");
Expand Down Expand Up @@ -611,7 +606,6 @@ export class AssembledTransaction<T> {
const sent = await SentTransaction.init(
signTransaction,
typeChecked,
updateTimeout
);
return sent;
};
Expand Down Expand Up @@ -797,7 +791,7 @@ export class AssembledTransaction<T> {
* returns `false`, then you need to call `signAndSend` on this transaction.
*/
get isReadCall(): boolean {
const authsCount = this.simulationData.result.auth.length;
const authsCount = this.simulationData.result?.auth.length;
const writeLength = this.simulationData.transactionData
.resources()
.footprint()
Expand Down Expand Up @@ -834,9 +828,7 @@ export class AssembledTransaction<T> {
minResourceFee: string;
transactionData: SorobanDataBuilder;
},
/**
* The account that is executing the footprint restore operation.
*/
/** The account that is executing the footprint restore operation. */
account?: Account
): Promise<Api.GetTransactionResponse> {
if(!this.options.signTransaction){
Expand All @@ -850,14 +842,10 @@ export class AssembledTransaction<T> {
account,
restorePreamble.minResourceFee
);
const sentTransaction = await restoreTx.signAndSend({
updateTimeout: false,
force: true,
});
const sentTransaction = await restoreTx.signAndSend();
if (!sentTransaction.getTransactionResponse) {
// todo make better error message
throw new AssembledTransaction.Errors.RestoreFailure(
`Failure during restore. \n${JSON.stringify(sentTransaction)}`
throw new AssembledTransaction.Errors.RestorationFailure(
`The attempt at automatic restore failed. \n${JSON.stringify(sentTransaction)}`
);
}
return sentTransaction.getTransactionResponse;
Expand Down
25 changes: 10 additions & 15 deletions src/contract/sent_transaction.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* disable max-classes rule, because extending error shouldn't count! */
/* eslint max-classes-per-file: 0 */
import { SorobanDataBuilder, TransactionBuilder } from "@stellar/stellar-base";
import { TransactionBuilder } from "@stellar/stellar-base";
import type { ClientOptions, MethodOptions, Tx } from "./types";
import { Server } from "../rpc/server"
import { Api } from "../rpc/api"
Expand Down Expand Up @@ -76,27 +76,22 @@ export class SentTransaction<T> {
signTransaction: ClientOptions["signTransaction"],
/** {@link AssembledTransaction} from which this SentTransaction was initialized */
assembled: AssembledTransaction<U>,
updateTimeout: boolean = true,
): Promise<SentTransaction<U>> => {
const tx = new SentTransaction(signTransaction, assembled);
const sent = await tx.send({ updateTimeout });
const sent = await tx.send();
return sent;
};

private send = async ({ updateTimeout }: {updateTimeout?: boolean } = { updateTimeout: true }): Promise<this> => {
private send = async (): Promise<this> => {
const timeoutInSeconds =
this.assembled.options.timeoutInSeconds ?? DEFAULT_TIMEOUT;
if(updateTimeout) {
this.assembled.built = TransactionBuilder.cloneFrom(this.assembled.built!, {
fee: this.assembled.built!.fee,
timebounds: undefined,
sorobanData: new SorobanDataBuilder(
this.assembled.simulationData.transactionData.toXDR(),
).build(),
})
.setTimeout(timeoutInSeconds)
.build();
}
this.assembled.built = TransactionBuilder.cloneFrom(this.assembled.built!, {
fee: this.assembled.built!.fee,
timebounds: undefined, // intentionally don't clone timebounds
sorobanData: this.assembled.simulationData.transactionData
})
.setTimeout(timeoutInSeconds)
.build();

const signature = await this.signTransaction!(
// `signAndSend` checks for `this.built` before calling `SentTransaction.init`
Expand Down
4 changes: 1 addition & 3 deletions test/unit/server/soroban/assembled_transaction_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,7 @@ describe("AssembledTransaction.buildFootprintRestoreTransaction", () => {
),
52641,
)
.then((txn) => txn.signAndSend({force: true, ...wallet,
updateTimeout: false
}))
.then((txn) => txn.signAndSend({ ...wallet }))
.then((result) => {
expect(result.getTransactionResponse.status).to.equal(rpc.Api.GetTransactionStatus.SUCCESS);
done();
Expand Down

0 comments on commit ae4db84

Please sign in to comment.