Skip to content

Commit

Permalink
fix!: create a new CML scope for every call of BuildTx in selection c…
Browse files Browse the repository at this point in the history
…onstraints
  • Loading branch information
mkazlauskas committed Nov 24, 2022
1 parent 9829d82 commit e576446
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 20 deletions.
30 changes: 15 additions & 15 deletions packages/input-selection/src/selectionConstraints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import {
ComputeSelectionLimit,
EstimateTxFee,
ProtocolParametersForInputSelection,
ProtocolParametersRequiredByInputSelection,
SelectionConstraints,
SelectionSkeleton,
TokenBundleSizeExceedsLimit
} from './types';
import { ProtocolParametersRequiredByInputSelection } from '.';
import { usingAutoFree } from '@cardano-sdk/util';
import { ManagedFreeableScope, usingAutoFree } from '@cardano-sdk/util';

export type BuildTx = (selection: SelectionSkeleton) => Promise<CML.Transaction>;
export type BuildTx = (selection: SelectionSkeleton, scope: ManagedFreeableScope) => Promise<CML.Transaction>;

export interface DefaultSelectionConstraintsProps {
protocolParameters: ProtocolParametersForInputSelection;
Expand All @@ -26,10 +26,10 @@ export const computeMinimumCost =
}: Pick<ProtocolParametersRequiredByInputSelection, 'minFeeCoefficient' | 'minFeeConstant'>,
buildTx: BuildTx
): EstimateTxFee =>
async (selection) => {
const tx = await buildTx(selection);
(selection) =>
usingAutoFree(async (scope) => {
const tx = await buildTx(selection, scope);

return usingAutoFree((scope) => {
// TODO: Get this from cardano-services
const priceMem = scope.manage(
CML.UnitInterval.new(scope.manage(CML.BigNum.from_str('577')), scope.manage(CML.BigNum.from_str('10000')))
Expand All @@ -48,7 +48,6 @@ export const computeMinimumCost =
const minFee = scope.manage(CML.min_fee(tx, linearFee, exInitPrices));
return BigInt(minFee.to_str());
});
};

export const computeMinimumCoinQuantity =
(coinsPerUtxoByte: ProtocolParametersRequiredByInputSelection['coinsPerUtxoByte']): ComputeMinimumCoinQuantity =>
Expand Down Expand Up @@ -91,14 +90,15 @@ const getTxSize = (tx: CML.Transaction) => tx.to_bytes().length;
*/
export const computeSelectionLimit =
(maxTxSize: ProtocolParametersRequiredByInputSelection['maxTxSize'], buildTx: BuildTx): ComputeSelectionLimit =>
async (selectionSkeleton) => {
const tx = await buildTx(selectionSkeleton);
const txSize = getTxSize(tx);
if (txSize <= maxTxSize) {
return selectionSkeleton.inputs.size;
}
return selectionSkeleton.inputs.size - 1;
};
(selectionSkeleton) =>
usingAutoFree(async (scope) => {
const tx = scope.manage(await buildTx(selectionSkeleton, scope));
const txSize = getTxSize(tx);
if (txSize <= maxTxSize) {
return selectionSkeleton.inputs.size;
}
return selectionSkeleton.inputs.size - 1;
});

export const defaultSelectionConstraints = ({
protocolParameters: { coinsPerUtxoByte, maxTxSize, maxValueSize, minFeeCoefficient, minFeeConstant },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,7 @@ export class SingleAddressWallet implements ObservableWallet {
async initializeTx(props: InitializeTxProps): Promise<InitializeTxResult> {
const scope = new ManagedFreeableScope();
const { constraints, utxo, implicitCoin, validityInterval, changeAddress, withdrawals } = await this.#prepareTx(
props,
scope
props
);
const { selection: inputSelection } = await this.#inputSelector.select({
constraints,
Expand Down
5 changes: 2 additions & 3 deletions packages/wallet/src/SingleAddressWallet/prepareTx.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Cardano, coreToCml } from '@cardano-sdk/core';
import { FinalizeTxProps, InitializeTxProps, ObservableWallet } from '../types';
import { Logger } from 'ts-log';
import { ManagedFreeableScope } from '@cardano-sdk/util';
import { Observable, combineLatest, filter, firstValueFrom, lastValueFrom, map, take } from 'rxjs';
import { createTransactionInternals, ensureValidityInterval } from '../Transaction';
import { defaultSelectionConstraints } from '@cardano-sdk/input-selection';
Expand All @@ -20,7 +19,7 @@ export interface PrepareTxDependencies {

export const createTxPreparer =
({ wallet, signer, logger }: PrepareTxDependencies) =>
async (props: InitializeTxProps, scope: ManagedFreeableScope) => {
async (props: InitializeTxProps) => {
await firstValueFrom(wallet.syncStatus.isSettled$.pipe(filter((isSettled) => isSettled)));
const withdrawals$: Observable<Cardano.Withdrawal[] | undefined> = wallet.delegation.rewardAccounts$.pipe(
map((accounts) => accounts.filter((account) => account.rewardBalance)),
Expand All @@ -41,7 +40,7 @@ export const createTxPreparer =
map(([tip, utxo, protocolParameters, [{ address: changeAddress }], withdrawals]) => {
const validityInterval = ensureValidityInterval(tip.slot, props.options?.validityInterval);
const constraints = defaultSelectionConstraints({
buildTx: async (inputSelection) => {
buildTx: async (inputSelection, scope) => {
logger.debug('Building TX for selection constraints', inputSelection);
if (withdrawals?.length) {
logger.debug('Adding rewards withdrawal in the transaction', withdrawals);
Expand Down

0 comments on commit e576446

Please sign in to comment.