Skip to content

Commit

Permalink
refactor!: make tx validityInterval an optional
Browse files Browse the repository at this point in the history
BREAKING CHANGE:

- make `TxBodyAlonzo.validityInterval` an optional field aligned with Ogmios schema
  • Loading branch information
Ivaylo Andonov committed Dec 5, 2022
1 parent bc62f8b commit fa1c487
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 32 deletions.
6 changes: 3 additions & 3 deletions packages/core/src/CML/coreToCml/coreToCml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,13 +375,13 @@ export const txBody = (
txInputs(scope, inputs),
cslOutputs,
scope.manage(BigNum.from_str(fee.toString())),
BigNum.from_str(validityInterval.invalidHereafter ? validityInterval.invalidHereafter.toString() : '0')
BigNum.from_str(validityInterval?.invalidHereafter ? validityInterval.invalidHereafter.toString() : '0')
)
);

if (validityInterval.invalidBefore) {
if (validityInterval?.invalidBefore) {
cslBody.set_validity_start_interval(
BigNum.from_str(validityInterval.invalidBefore ? validityInterval.invalidBefore.toString() : '0')
BigNum.from_str(validityInterval?.invalidBefore ? validityInterval.invalidBefore.toString() : '0')
);
}
if (mint) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/Cardano/types/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export interface HydratedTxBody {
collaterals?: HydratedTxIn[];
outputs: TxOut[];
fee: Lovelace;
validityInterval: ValidityInterval;
validityInterval?: ValidityInterval;
withdrawals?: Withdrawal[];
certificates?: Certificate[];
mint?: TokenMap;
Expand Down
4 changes: 2 additions & 2 deletions packages/core/test/CML/coreToCml.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ describe('coreToCml', () => {
expect(Buffer.from(scope.manage(input0.transaction_id()).to_bytes()).toString('hex')).toBe(txBody.inputs[0].txId);
expect(output0AmountCoin.to_str()).toBe(txBody.outputs[0].value.coins.toString());
expect(Number(scope.manage(cmlBody.validity_start_interval())?.to_str())).toBe(
txBody.validityInterval.invalidBefore
txBody.validityInterval!.invalidBefore
);
expect(Number(scope.manage(cmlBody.ttl())?.to_str())).toBe(txBody.validityInterval.invalidHereafter);
expect(Number(scope.manage(cmlBody.ttl())?.to_str())).toBe(txBody.validityInterval!.invalidHereafter);
expect(withdrawal0!.to_str()).toBe(txBody.withdrawals![0].quantity.toString());
const mint = scope.manage(cmlBody.multiassets())!;
const scriptHashes = scope.manage(mint.keys());
Expand Down
14 changes: 7 additions & 7 deletions packages/wallet/src/services/SmartTxSubmitProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,28 +51,28 @@ export class SmartTxSubmitProvider implements TxSubmitProvider {

submitTx(args: SubmitTxArgs): Promise<void> {
const {
body: {
validityInterval: { invalidBefore, invalidHereafter }
}
body: { validityInterval }
} = cmlUtil.deserializeTx(args.signedTransaction);

const onlineAndWithinValidityInterval$ = combineLatest([this.#connectionStatus$, this.#tip$]).pipe(
tap(([_, { slot }]) => {
if (slot >= (invalidHereafter || Number.POSITIVE_INFINITY))
if (slot >= (validityInterval?.invalidHereafter || Number.POSITIVE_INFINITY))
throw new ProviderError(
ProviderFailure.BadRequest,
new CardanoNodeErrors.TxSubmissionErrors.OutsideOfValidityIntervalError({
outsideOfValidityInterval: {
currentSlot: slot.valueOf(),
interval: {
invalidBefore: invalidBefore?.valueOf() || null,
invalidHereafter: invalidHereafter?.valueOf() || null
invalidBefore: validityInterval?.invalidBefore?.valueOf() || null,
invalidHereafter: validityInterval?.invalidHereafter?.valueOf() || null
}
}
})
);
}),
filter(
([connectionStatus, { slot }]) => connectionStatus === ConnectionStatus.up && slot >= (invalidBefore || 0)
([connectionStatus, { slot }]) =>
connectionStatus === ConnectionStatus.up && slot >= (validityInterval?.invalidBefore || 0)
),
take(1)
);
Expand Down
2 changes: 1 addition & 1 deletion packages/wallet/src/services/TransactionsTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ export const createTransactionsTracker = (
mergeMap((group$) =>
group$.pipe(
switchMap(({ tx }) => {
const invalidHereafter = tx.body.validityInterval.invalidHereafter;
const invalidHereafter = tx.body.validityInterval?.invalidHereafter;
return race(
rollback$.pipe(
map((rolledBackTx) => rolledBackTx.id),
Expand Down
4 changes: 3 additions & 1 deletion packages/wallet/test/SingleAddressWallet/rollback.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ describe('SingleAddressWallet rollback', () => {

const histTx1 = mocks.queryTransactionsResult.pageResults[0];
const rollBackTx = { ...mocks.queryTransactionsResult.pageResults[1], id: tx.id };
rollBackTx.body.validityInterval.invalidHereafter = Cardano.Slot(secondTip.slot.valueOf() + 1);
if (rollBackTx.body.validityInterval?.invalidHereafter) {
rollBackTx.body.validityInterval.invalidHereafter = Cardano.Slot(secondTip.slot.valueOf() + 1);
}

const newTx = {
...rollBackTx,
Expand Down
34 changes: 17 additions & 17 deletions packages/wallet/test/services/TransactionsTracker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,8 @@ describe('TransactionsTracker', () => {
it('emits at all relevant observable properties on timed out transaction', async () => {
const tx = queryTransactionsResult.pageResults[0];
createTestScheduler().run(({ hot, expectObservable }) => {
const tip1 = { slot: Cardano.Slot(tx.body.validityInterval.invalidHereafter!.valueOf() - 1) } as Cardano.Tip;
const tip2 = { slot: Cardano.Slot(tx.body.validityInterval.invalidHereafter!.valueOf() + 1) } as Cardano.Tip;
const tip1 = { slot: Cardano.Slot(tx.body.validityInterval!.invalidHereafter!.valueOf()! - 1) } as Cardano.Tip;
const tip2 = { slot: Cardano.Slot(tx.body.validityInterval!.invalidHereafter!.valueOf()! + 1) } as Cardano.Tip;
const failedToSubmit$ = hot<FailedTx>('-----|');
const tip$ = hot<Cardano.Tip>('--ab-|', { a: tip1, b: tip2 });
const submitting$ = hot('-a---|', { a: tx });
Expand Down Expand Up @@ -274,12 +274,12 @@ describe('TransactionsTracker', () => {
rollback of a transaction of which an output was used in a pending transaction interprets transaction as failed`, async () => {
const tx = queryTransactionsResult.pageResults[0];
createTestScheduler().run(({ cold, hot, expectObservable }) => {
const tip1 = { slot: Cardano.Slot(tx.body.validityInterval.invalidHereafter!.valueOf() - 1) } as Cardano.Tip;
const tip1 = { slot: Cardano.Slot(tx.body.validityInterval!.invalidHereafter!.valueOf() - 1) } as Cardano.Tip;
const failedToSubmit$ = hot<FailedTx>('-----|');
const tip$ = cold('a', { a: tip1 });
const submitting$ = hot('-a---|', { a: tx });
const pending$ = hot( '--a-a|', { a: tx }); // second emission must not re-add it to inFlight$
const rollback$ = hot( '---a-|', { a: { id: tx.body.inputs[0].txId } as Cardano.HydratedTx });
const pending$ = hot('--a-a|', { a: tx }); // second emission must not re-add it to inFlight$
const rollback$ = hot('---a-|', { a: { id: tx.body.inputs[0].txId } as Cardano.HydratedTx });
const transactionsSource$ = hot<Cardano.HydratedTx[]>('-----|');
const transactionsTracker = createTransactionsTracker(
{
Expand All @@ -301,8 +301,8 @@ describe('TransactionsTracker', () => {
transactionsSource$
}
);
expectObservable(transactionsTracker.outgoing.submitting$).toBe( '-a---|', { a: tx });
expectObservable(transactionsTracker.outgoing.pending$).toBe( '--a-a|', { a: tx });
expectObservable(transactionsTracker.outgoing.submitting$).toBe('-a---|', { a: tx });
expectObservable(transactionsTracker.outgoing.pending$).toBe('--a-a|', { a: tx });
expectObservable(transactionsTracker.outgoing.failed$.pipe(map(err => err.reason))).toBe('---a-|', {
a: TransactionFailure.InvalidTransaction
});
Expand Down Expand Up @@ -366,7 +366,7 @@ describe('TransactionsTracker', () => {
b: { slot: submittedAt2 } as Cardano.Tip
});
const submitting$ = hot('-a-b--|', { a: tx, b: tx });
const pending$ = hot( '--a-b-|', { a: tx, b: tx });
const pending$ = hot('--a-b-|', { a: tx, b: tx });
const transactionsSource$ = hot<Cardano.HydratedTx[]>('-a---b|', {
a: [],
b: [tx]
Expand All @@ -393,8 +393,8 @@ describe('TransactionsTracker', () => {
}
);
expectObservable(transactionsTracker.outgoing.submitting$).toBe('-a-b--|', { a: tx, b: tx });
expectObservable(transactionsTracker.outgoing.pending$).toBe( '--a-b-|', { a: tx, b: tx });
expectObservable(transactionsTracker.outgoing.inFlight$).toBe( 'abcdef|', {
expectObservable(transactionsTracker.outgoing.pending$).toBe('--a-b-|', { a: tx, b: tx });
expectObservable(transactionsTracker.outgoing.inFlight$).toBe('abcdef|', {
a: [],
b: [{ tx }],
c: [{ submittedAt: submittedAt1, tx }],
Expand All @@ -414,14 +414,14 @@ describe('TransactionsTracker', () => {
createTestScheduler().run(({ hot, expectObservable }) => {
const submittedAt1 = Cardano.Slot(123);
const submittedAt2 = Cardano.Slot(124);
const tip$ = hot( '--a-b-|', {
const tip$ = hot('--a-b-|', {
a: { slot: submittedAt1 } as Cardano.Tip,
b: { slot: submittedAt2 } as Cardano.Tip
});
const submitting$ = hot( '-a-b--|', { a: tx, b: tx });
const pending$ = hot<Cardano.Tx>( '------|');
const submitting$ = hot('-a-b--|', { a: tx, b: tx });
const pending$ = hot<Cardano.Tx>('------|');
const transactionsSource$ = hot<Cardano.HydratedTx[]>('a-----|', { a: [] });
const failedToSubmit$ = hot<FailedTx>( '-----a|', {
const failedToSubmit$ = hot<FailedTx>('-----a|', {
a: { reason: TransactionFailure.FailedToSubmit, tx }
});
const transactionsTracker = createTransactionsTracker(
Expand All @@ -445,11 +445,11 @@ describe('TransactionsTracker', () => {
}
);
expectObservable(transactionsTracker.outgoing.submitting$).toBe('-a-b--|', { a: tx, b: tx });
expectObservable(transactionsTracker.outgoing.inFlight$).toBe( 'ab-c-a|', { a: [], b: [{ tx }], c: [{ tx }] });
expectObservable(transactionsTracker.outgoing.failed$).toBe( '-----a|', {
expectObservable(transactionsTracker.outgoing.inFlight$).toBe('ab-c-a|', { a: [], b: [{ tx }], c: [{ tx }] });
expectObservable(transactionsTracker.outgoing.failed$).toBe('-----a|', {
a: { reason: TransactionFailure.FailedToSubmit, tx }
});
expectObservable(transactionsTracker.outgoing.confirmed$).toBe( '------|');
expectObservable(transactionsTracker.outgoing.confirmed$).toBe('------|');
});
});

Expand Down

0 comments on commit fa1c487

Please sign in to comment.