gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: wallet-core: move contract te


From: gnunet
Subject: [taler-wallet-core] branch master updated: wallet-core: move contract terms to object store
Date: Tue, 12 Sep 2023 13:49:30 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new 4b0680eef wallet-core: move contract terms to object store
4b0680eef is described below

commit 4b0680eefa0dcb2e9b00342949393e4b166eecb2
Author: Florian Dold <florian@dold.me>
AuthorDate: Tue Sep 12 13:48:52 2023 +0200

    wallet-core: move contract terms to object store
---
 packages/taler-wallet-core/src/db.ts               |  21 ++--
 packages/taler-wallet-core/src/dbless.ts           |  24 +++--
 .../taler-wallet-core/src/operations/deposits.ts   |  35 ++++--
 .../src/operations/pay-peer-pull-debit.ts          | 117 ++++++++++-----------
 .../src/operations/transactions.ts                 |  42 ++++++--
 5 files changed, 142 insertions(+), 97 deletions(-)

diff --git a/packages/taler-wallet-core/src/db.ts 
b/packages/taler-wallet-core/src/db.ts
index 04c3ce723..9bf9a29cc 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -28,6 +28,7 @@ import {
 } from "@gnu-taler/idb-bridge";
 import {
   AgeCommitmentProof,
+  AmountJson,
   AmountString,
   Amounts,
   AttentionInfo,
@@ -1640,6 +1641,15 @@ export interface DepositTrackingInfo {
 export interface DepositGroupRecord {
   depositGroupId: string;
 
+  currency: string;
+
+  /**
+   * Instructed amount.
+   */
+  amount: AmountString;
+
+  wireTransferDeadline: TalerProtocolTimestamp;
+
   merchantPub: string;
   merchantPriv: string;
 
@@ -1655,13 +1665,6 @@ export interface DepositGroupRecord {
     salt: string;
   };
 
-  /**
-   * Verbatim contract terms.
-   * 
-   * FIXME: Move this to the contract terms object store!
-   */
-  contractTermsRaw: MerchantContractTerms;
-
   contractTermsHash: string;
 
   payCoinSelection: PayCoinSelection;
@@ -1981,7 +1984,9 @@ export interface PeerPullPaymentIncomingRecord {
 
   exchangeBaseUrl: string;
 
-  contractTerms: PeerContractTerms;
+  amount: AmountString;
+
+  contractTermsHash: string;
 
   timestampCreated: TalerPreciseTimestamp;
 
diff --git a/packages/taler-wallet-core/src/dbless.ts 
b/packages/taler-wallet-core/src/dbless.ts
index 11c6c0f74..65c293bdf 100644
--- a/packages/taler-wallet-core/src/dbless.ts
+++ b/packages/taler-wallet-core/src/dbless.ts
@@ -33,12 +33,13 @@ import {
   AmountString,
   codecForAny,
   codecForBankWithdrawalOperationPostResponse,
-  codecForDepositSuccess,
+  codecForBatchDepositSuccess,
   codecForExchangeMeltResponse,
   codecForExchangeRevealResponse,
   codecForWithdrawResponse,
   DenominationPubKey,
   encodeCrock,
+  ExchangeBatchDepositRequest,
   ExchangeMeltRequest,
   ExchangeProtocolVersion,
   ExchangeWithdrawRequest,
@@ -256,22 +257,27 @@ export async function depositCoin(args: {
     refundDeadline: refundDeadline,
     wireInfoHash: hashWire(depositPayto, wireSalt),
   });
-  const requestBody = {
-    contribution: Amounts.stringify(dp.contribution),
+  const requestBody: ExchangeBatchDepositRequest = {
+    coins: [
+      {
+        contribution: Amounts.stringify(dp.contribution),
+        coin_pub: dp.coin_pub,
+        coin_sig: dp.coin_sig,
+        denom_pub_hash: dp.h_denom,
+        ub_sig: dp.ub_sig,
+      },
+    ],
     merchant_payto_uri: depositPayto,
     wire_salt: wireSalt,
     h_contract_terms: contractTermsHash,
-    ub_sig: coin.denomSig,
     timestamp: depositTimestamp,
     wire_transfer_deadline: wireTransferDeadline,
     refund_deadline: refundDeadline,
-    coin_sig: dp.coin_sig,
-    denom_pub_hash: dp.h_denom,
     merchant_pub: merchantPub,
   };
-  const url = new URL(`coins/${dp.coin_pub}/deposit`, dp.exchange_url);
-  const httpResp = await http.postJson(url.href, requestBody);
-  await readSuccessResponseJsonOrThrow(httpResp, codecForDepositSuccess());
+  const url = new URL(`batch-deposit`, dp.exchange_url);
+  const httpResp = await http.fetch(url.href, { body: requestBody });
+  await readSuccessResponseJsonOrThrow(httpResp, 
codecForBatchDepositSuccess());
 }
 
 export async function refreshCoin(req: {
diff --git a/packages/taler-wallet-core/src/operations/deposits.ts 
b/packages/taler-wallet-core/src/operations/deposits.ts
index a3483a332..2de8f30a1 100644
--- a/packages/taler-wallet-core/src/operations/deposits.ts
+++ b/packages/taler-wallet-core/src/operations/deposits.ts
@@ -884,8 +884,18 @@ async function processDepositGroupPendingDeposit(
 ): Promise<TaskRunResult> {
   logger.info("processing deposit group in pending(deposit)");
   const depositGroupId = depositGroup.depositGroupId;
+  const contractTermsRec = await ws.db
+    .mktx((x) => [x.contractTerms])
+    .runReadOnly(async (tx) => {
+      return tx.contractTerms.get(depositGroup.contractTermsHash);
+    });
+  if (!contractTermsRec) {
+    throw Error("contract terms for deposit not found in database");
+  }
+  const contractTerms: MerchantContractTerms =
+    contractTermsRec.contractTermsRaw;
   const contractData = extractContractData(
-    depositGroup.contractTermsRaw,
+    contractTermsRec.contractTermsRaw,
     depositGroup.contractTermsHash,
     "",
   );
@@ -921,12 +931,11 @@ async function processDepositGroupPendingDeposit(
       coins,
       h_contract_terms: depositGroup.contractTermsHash,
       merchant_payto_uri: depositGroup.wire.payto_uri,
-      merchant_pub: depositGroup.contractTermsRaw.merchant_pub,
-      timestamp: depositGroup.contractTermsRaw.timestamp,
+      merchant_pub: contractTerms.merchant_pub,
+      timestamp: contractTerms.timestamp,
       wire_salt: depositGroup.wire.salt,
-      wire_transfer_deadline:
-        depositGroup.contractTermsRaw.wire_transfer_deadline,
-      refund_deadline: depositGroup.contractTermsRaw.refund_deadline,
+      wire_transfer_deadline: contractTerms.wire_transfer_deadline,
+      refund_deadline: contractTerms.refund_deadline,
     };
 
     for (let i = 0; i < depositPermissions.length; i++) {
@@ -1086,7 +1095,10 @@ async function trackDeposit(
   coinPub: string,
   exchangeUrl: string,
 ): Promise<TrackTransaction> {
-  const wireHash = depositGroup.contractTermsRaw.h_wire;
+  const wireHash = hashWire(
+    depositGroup.wire.payto_uri,
+    depositGroup.wire.salt,
+  );
 
   const url = new URL(
     
`deposits/${wireHash}/${depositGroup.merchantPub}/${depositGroup.contractTermsHash}/${coinPub}`,
@@ -1358,8 +1370,9 @@ export async function createDepositGroup(
 
   const depositGroup: DepositGroupRecord = {
     contractTermsHash,
-    contractTermsRaw: contractTerms,
     depositGroupId,
+    currency: Amounts.currencyOf(totalDepositCost),
+    amount: contractData.amount,
     noncePriv: noncePair.priv,
     noncePub: noncePair.pub,
     timestampCreated: AbsoluteTime.toPreciseTimestamp(now),
@@ -1375,6 +1388,7 @@ export async function createDepositGroup(
     counterpartyEffectiveDepositAmount: Amounts.stringify(
       counterpartyEffectiveDepositAmount,
     ),
+    wireTransferDeadline: contractTerms.wire_transfer_deadline,
     wire: {
       payto_uri: req.depositPaytoUri,
       salt: wireSalt,
@@ -1395,6 +1409,7 @@ export async function createDepositGroup(
       x.denominations,
       x.refreshGroups,
       x.coinAvailability,
+      x.contractTerms,
     ])
     .runReadWrite(async (tx) => {
       await spendCoins(ws, tx, {
@@ -1406,6 +1421,10 @@ export async function createDepositGroup(
         refreshReason: RefreshReason.PayDeposit,
       });
       await tx.depositGroups.put(depositGroup);
+      await tx.contractTerms.put({
+        contractTermsRaw: contractTerms,
+        h: contractTermsHash,
+      });
       return computeDepositTransactionStatus(depositGroup);
     });
 
diff --git a/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts 
b/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts
index f357c41d5..5bcfa3418 100644
--- a/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts
+++ b/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts
@@ -19,6 +19,7 @@ import {
   Amounts,
   CoinRefreshRequest,
   ConfirmPeerPullDebitRequest,
+  ContractTermsUtil,
   ExchangePurseDeposits,
   HttpStatusCode,
   Logger,
@@ -103,9 +104,7 @@ async function handlePurseCreationConflict(
     throw new TalerProtocolViolationError();
   }
 
-  const instructedAmount = Amounts.parseOrThrow(
-    peerPullInc.contractTerms.amount,
-  );
+  const instructedAmount = Amounts.parseOrThrow(peerPullInc.amount);
 
   const sel = peerPullInc.coinSel;
   if (!sel) {
@@ -142,9 +141,7 @@ async function handlePurseCreationConflict(
   await ws.db
     .mktx((x) => [x.peerPullDebit])
     .runReadWrite(async (tx) => {
-      const myPpi = await tx.peerPullDebit.get(
-        peerPullInc.peerPullDebitId,
-      );
+      const myPpi = await tx.peerPullDebit.get(peerPullInc.peerPullDebitId);
       if (!myPpi) {
         return;
       }
@@ -220,9 +217,7 @@ async function processPeerPullDebitPendingDeposit(
       const transitionInfo = await ws.db
         .mktx((x) => [x.peerPullDebit])
         .runReadWrite(async (tx) => {
-          const pi = await tx.peerPullDebit.get(
-            peerPullDebitId,
-          );
+          const pi = await tx.peerPullDebit.get(peerPullDebitId);
           if (!pi) {
             throw Error("peer pull payment not found anymore");
           }
@@ -248,9 +243,7 @@ async function processPeerPullDebitPendingDeposit(
           x.coins,
         ])
         .runReadWrite(async (tx) => {
-          const pi = await tx.peerPullDebit.get(
-            peerPullDebitId,
-          );
+          const pi = await tx.peerPullDebit.get(peerPullDebitId);
           if (!pi) {
             throw Error("peer pull payment not found anymore");
           }
@@ -335,9 +328,7 @@ async function processPeerPullDebitAbortingRefresh(
         }
       }
       if (newOpState) {
-        const newDg = await tx.peerPullDebit.get(
-          peerPullDebitId,
-        );
+        const newDg = await tx.peerPullDebit.get(peerPullDebitId);
         if (!newDg) {
           return;
         }
@@ -391,9 +382,7 @@ export async function confirmPeerPullDebit(
   } else if (req.peerPullDebitId) {
     peerPullDebitId = req.peerPullDebitId;
   } else {
-    throw Error(
-      "invalid request, transactionId or peerPullDebitId required",
-    );
+    throw Error("invalid request, transactionId or peerPullDebitId required");
   }
 
   const peerPullInc = await ws.db
@@ -408,9 +397,7 @@ export async function confirmPeerPullDebit(
     );
   }
 
-  const instructedAmount = Amounts.parseOrThrow(
-    peerPullInc.contractTerms.amount,
-  );
+  const instructedAmount = Amounts.parseOrThrow(peerPullInc.amount);
 
   const coinSelRes = await selectPeerCoins(ws, { instructedAmount });
   logger.info(`selected p2p coins (pull): ${j2s(coinSelRes)}`);
@@ -454,9 +441,7 @@ export async function confirmPeerPullDebit(
         refreshReason: RefreshReason.PayPeerPull,
       });
 
-      const pi = await tx.peerPullDebit.get(
-        peerPullDebitId,
-      );
+      const pi = await tx.peerPullDebit.get(peerPullDebitId);
       if (!pi) {
         throw Error();
       }
@@ -498,27 +483,36 @@ export async function preparePeerPullDebit(
     throw Error("got invalid taler://pay-pull URI");
   }
 
-  const existingPullIncomingRecord = await ws.db
-    .mktx((x) => [x.peerPullDebit])
+  const existing = await ws.db
+    .mktx((x) => [x.peerPullDebit, x.contractTerms])
     .runReadOnly(async (tx) => {
-      return tx.peerPullDebit.indexes.byExchangeAndContractPriv.get([
-        uri.exchangeBaseUrl,
-        uri.contractPriv,
-      ]);
+      const peerPullDebitRecord =
+        await tx.peerPullDebit.indexes.byExchangeAndContractPriv.get([
+          uri.exchangeBaseUrl,
+          uri.contractPriv,
+        ]);
+      if (!peerPullDebitRecord) {
+        return;
+      }
+      const contractTerms = await tx.contractTerms.get(
+        peerPullDebitRecord.contractTermsHash,
+      );
+      if (!contractTerms) {
+        return;
+      }
+      return { peerPullDebitRecord, contractTerms };
     });
 
-  if (existingPullIncomingRecord) {
+  if (existing) {
     return {
-      amount: existingPullIncomingRecord.contractTerms.amount,
-      amountRaw: existingPullIncomingRecord.contractTerms.amount,
-      amountEffective: existingPullIncomingRecord.totalCostEstimated,
-      contractTerms: existingPullIncomingRecord.contractTerms,
-      peerPullDebitId:
-        existingPullIncomingRecord.peerPullDebitId,
+      amount: existing.peerPullDebitRecord.amount,
+      amountRaw: existing.peerPullDebitRecord.amount,
+      amountEffective: existing.peerPullDebitRecord.totalCostEstimated,
+      contractTerms: existing.contractTerms.contractTermsRaw,
+      peerPullDebitId: existing.peerPullDebitRecord.peerPullDebitId,
       transactionId: constructTransactionIdentifier({
         tag: TransactionType.PeerPullDebit,
-        peerPullDebitId:
-          existingPullIncomingRecord.peerPullDebitId,
+        peerPullDebitId: existing.peerPullDebitRecord.peerPullDebitId,
       }),
     };
   }
@@ -566,6 +560,8 @@ export async function preparePeerPullDebit(
     throw Error("pull payments without contract terms not supported yet");
   }
 
+  const contractTermsHash = ContractTermsUtil.hashContractTerms(contractTerms);
+
   // FIXME: Why don't we compute the totalCost here?!
 
   const instructedAmount = Amounts.parseOrThrow(contractTerms.amount);
@@ -588,18 +584,23 @@ export async function preparePeerPullDebit(
   );
 
   await ws.db
-    .mktx((x) => [x.peerPullDebit])
+    .mktx((x) => [x.peerPullDebit, x.contractTerms])
     .runReadWrite(async (tx) => {
-      await tx.peerPullDebit.add({
-        peerPullDebitId,
-        contractPriv: contractPriv,
-        exchangeBaseUrl: exchangeBaseUrl,
-        pursePub: pursePub,
-        timestampCreated: TalerPreciseTimestamp.now(),
-        contractTerms,
-        status: PeerPullDebitRecordStatus.DialogProposed,
-        totalCostEstimated: Amounts.stringify(totalAmount),
-      });
+      await tx.contractTerms.put({
+        h: contractTermsHash,
+        contractTermsRaw: contractTerms,
+      }),
+        await tx.peerPullDebit.add({
+          peerPullDebitId,
+          contractPriv: contractPriv,
+          exchangeBaseUrl: exchangeBaseUrl,
+          pursePub: pursePub,
+          timestampCreated: TalerPreciseTimestamp.now(),
+          contractTermsHash,
+          amount: contractTerms.amount,
+          status: PeerPullDebitRecordStatus.DialogProposed,
+          totalCostEstimated: Amounts.stringify(totalAmount),
+        });
     });
 
   return {
@@ -631,9 +632,7 @@ export async function suspendPeerPullDebitTransaction(
   const transitionInfo = await ws.db
     .mktx((x) => [x.peerPullDebit])
     .runReadWrite(async (tx) => {
-      const pullDebitRec = await tx.peerPullDebit.get(
-        peerPullDebitId,
-      );
+      const pullDebitRec = await tx.peerPullDebit.get(peerPullDebitId);
       if (!pullDebitRec) {
         logger.warn(`peer pull debit ${peerPullDebitId} not found`);
         return;
@@ -692,9 +691,7 @@ export async function abortPeerPullDebitTransaction(
   const transitionInfo = await ws.db
     .mktx((x) => [x.peerPullDebit])
     .runReadWrite(async (tx) => {
-      const pullDebitRec = await tx.peerPullDebit.get(
-        peerPullDebitId,
-      );
+      const pullDebitRec = await tx.peerPullDebit.get(peerPullDebitId);
       if (!pullDebitRec) {
         logger.warn(`peer pull debit ${peerPullDebitId} not found`);
         return;
@@ -753,9 +750,7 @@ export async function failPeerPullDebitTransaction(
   const transitionInfo = await ws.db
     .mktx((x) => [x.peerPullDebit])
     .runReadWrite(async (tx) => {
-      const pullDebitRec = await tx.peerPullDebit.get(
-        peerPullDebitId,
-      );
+      const pullDebitRec = await tx.peerPullDebit.get(peerPullDebitId);
       if (!pullDebitRec) {
         logger.warn(`peer pull debit ${peerPullDebitId} not found`);
         return;
@@ -814,9 +809,7 @@ export async function resumePeerPullDebitTransaction(
   const transitionInfo = await ws.db
     .mktx((x) => [x.peerPullDebit])
     .runReadWrite(async (tx) => {
-      const pullDebitRec = await tx.peerPullDebit.get(
-        peerPullDebitId,
-      );
+      const pullDebitRec = await tx.peerPullDebit.get(peerPullDebitId);
       if (!pullDebitRec) {
         logger.warn(`peer pull debit ${peerPullDebitId} not found`);
         return;
diff --git a/packages/taler-wallet-core/src/operations/transactions.ts 
b/packages/taler-wallet-core/src/operations/transactions.ts
index 31655ad71..d7b277faf 100644
--- a/packages/taler-wallet-core/src/operations/transactions.ts
+++ b/packages/taler-wallet-core/src/operations/transactions.ts
@@ -346,11 +346,19 @@ export async function getTransactionById(
     }
     case TransactionType.PeerPullDebit: {
       return await ws.db
-        .mktx((x) => [x.peerPullDebit])
+        .mktx((x) => [x.peerPullDebit, x.contractTerms])
         .runReadWrite(async (tx) => {
           const debit = await tx.peerPullDebit.get(parsedTx.peerPullDebitId);
           if (!debit) throw Error("not found");
-          return buildTransactionForPullPaymentDebit(debit);
+          const contractTermsRec = await tx.contractTerms.get(
+            debit.contractTermsHash,
+          );
+          if (!contractTermsRec)
+            throw Error("contract terms for peer-pull-debit not found");
+          return buildTransactionForPullPaymentDebit(
+            debit,
+            contractTermsRec.contractTermsRaw,
+          );
         });
     }
 
@@ -477,6 +485,7 @@ function buildTransactionForPushPaymentDebit(
 
 function buildTransactionForPullPaymentDebit(
   pi: PeerPullPaymentIncomingRecord,
+  contractTerms: PeerContractTerms,
   ort?: OperationRetryRecord,
 ): Transaction {
   return {
@@ -485,12 +494,12 @@ function buildTransactionForPullPaymentDebit(
     txActions: computePeerPullDebitTransactionActions(pi),
     amountEffective: pi.coinSel?.totalCost
       ? pi.coinSel?.totalCost
-      : Amounts.stringify(pi.contractTerms.amount),
-    amountRaw: Amounts.stringify(pi.contractTerms.amount),
+      : Amounts.stringify(pi.amount),
+    amountRaw: Amounts.stringify(pi.amount),
     exchangeBaseUrl: pi.exchangeBaseUrl,
     info: {
-      expiration: pi.contractTerms.purse_expiration,
-      summary: pi.contractTerms.summary,
+      expiration: contractTerms.purse_expiration,
+      summary: contractTerms.summary,
     },
     timestamp: pi.timestampCreated,
     transactionId: constructTransactionIdentifier({
@@ -805,7 +814,7 @@ function buildTransactionForDeposit(
     amountEffective: Amounts.stringify(dg.totalPayCost),
     timestamp: dg.timestampCreated,
     targetPaytoUri: dg.wire.payto_uri,
-    wireTransferDeadline: dg.contractTermsRaw.wire_transfer_deadline,
+    wireTransferDeadline: dg.wireTransferDeadline,
     transactionId: constructTransactionIdentifier({
       tag: TransactionType.Deposit,
       depositGroupId: dg.depositGroupId,
@@ -980,7 +989,7 @@ export async function getTransactions(
       });
 
       await iterRecordsForPeerPullDebit(tx, filter, async (pi) => {
-        const amount = Amounts.parseOrThrow(pi.contractTerms.amount);
+        const amount = Amounts.parseOrThrow(pi.amount);
         if (shouldSkipCurrency(transactionsRequest, amount.currency)) {
           return;
         }
@@ -991,10 +1000,23 @@ export async function getTransactions(
           pi.status !== PeerPullDebitRecordStatus.PendingDeposit &&
           pi.status !== PeerPullDebitRecordStatus.Done
         ) {
+          // FIXME: Why?!
           return;
         }
 
-        transactions.push(buildTransactionForPullPaymentDebit(pi));
+        const contractTermsRec = await tx.contractTerms.get(
+          pi.contractTermsHash,
+        );
+        if (!contractTermsRec) {
+          return;
+        }
+
+        transactions.push(
+          buildTransactionForPullPaymentDebit(
+            pi,
+            contractTermsRec.contractTermsRaw,
+          ),
+        );
       });
 
       await iterRecordsForPeerPushCredit(tx, filter, async (pi) => {
@@ -1158,7 +1180,7 @@ export async function getTransactions(
       });
 
       await iterRecordsForDeposit(tx, filter, async (dg) => {
-        const amount = Amounts.parseOrThrow(dg.contractTermsRaw.amount);
+        const amount = Amounts.parseOrThrow(dg.amount);
         if (shouldSkipCurrency(transactionsRequest, amount.currency)) {
           return;
         }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]