web-dev-qa-db-fra.com

Comment obtenir / calculer CommitDigest lors de la validation d'une transaction dans AWS QLDB?

J'ai lu les documents en essayant de comprendre comment valider une transaction dans QLDB, et pour ce faire, un CommitDigest est requis, et les documents le décrivent comme:

Spécifie le résumé de validation pour la transaction à valider. Pour chaque transaction active, le résumé de validation doit être transmis. QLDB valide CommitDigest et rejette la validation avec une erreur si le résumé calculé sur le client ne correspond pas au résumé calculé par QLDB.

Donc CommitDigest doit être calculé, mais je ne suis pas sûr de ce qui est requis pour son calcul étant donné cet exemple:

// ** Start Session **
const startSessionResult = await qldbSession.sendCommand({
        StartSession: {
            LedgerName: ledgerName
        }
    }).promise(),
    sessionToken = startSessionResult.StartSession!.SessionToken!;

// ** Start Transaction **
const startTransactionResult = await qldbSession.sendCommand({
        StartTransaction: {},
        SessionToken: sessionToken
    }).promise(),
    transactionId = startTransactionResult.StartTransaction!.TransactionId!;

// ** Insert Document **
const executeStatementResult = await qldbSession.sendCommand({
        ExecuteStatement: {
            TransactionId: transactionId,
            Statement: `INSERT INTO sometable { 'id': 'abc123', 'userId': '123abc' }`
        },
        SessionToken: sessionToken
    }).promise(),
    documentId = getDocumentIdFromExecuteStateResult(executeStatementResult)

// ** Get Ledger Digest
const getDigestResult = await qldb.getDigest({
        Name: ledgerName
    }).promise(),
    ledgerDigest = getDigestResult.Digest;


// ** Commit Transaction **
// ** **The API call in question** **
const commitTransactionResult = await qldbSession.sendCommand({
    CommitTransaction: {
        TransactionId: transactionId,
        CommitDigest: `${commitDigest}` // <-- How to compute?
    },
    SessionToken: sessionToken
}).promise();
// *******************************


// ** End Session **
const endSession = await qldbSession.sendCommand({
    EndSession: {},
    SessionToken: sessionToken
}).promise();

De quoi ai-je besoin pour hacher pour CommitDigest dans l'appel api CommitTransaction?

9
Mike Richards

Mise à jour: le pilote Node.js est désormais disponible. Jetez un oeil à https://github.com/awslabs/Amazon-qldb-driver-nodejs/ .

Au moment de la rédaction de ce document, le pilote QLDB Node.js est toujours en développement. Cela va être assez difficile si vous essayez d'en créer un vous-même, donc je vous déconseille de le faire. Cela dit, je peux expliquer à la fois le but et l'algorithme derrière CommitDigest.

Le but est assez simple: garantir que les transactions ne sont validées que si le serveur a traité l'ensemble exact des déclarations envoyées par le client (toutes, dans l'ordre, pas de doublons). HTTP est une réponse à la demande et il est donc possible que les demandes soient abandonnées, traitées dans le désordre ou dupliquées. Les pilotes QLDB gèrent correctement la communication avec QLDB, mais avoir un résumé de validation étant dans le protocole, il est impossible pour une implémentation de réessayer incorrectement les requêtes et de valider la transaction. Par exemple, envisagez d'incrémenter un solde bancaire deux fois, car un message HTTP est réessayé même si la première demande a réussi.

L’algorithme est également assez simple: une valeur de hachage est amorcée avec l’identifiant de transaction puis mise à jour avec l’opérateur "point" QLDB. Chaque mise à jour "points" dans le hachage de l'instruction (sha256 de la chaîne PartiQL) ainsi que IonHash de toutes les valeurs de liaison. L'opérateur point est la façon dont QLDB fusionne les valeurs de hachage (c'est le même opérateur utilisé dans les API de vérification ) et est défini comme le hachage de la concaténation des deux hachages, ordonné par le (signé, petit -endian) comparaison octet-sage entre les deux hachages. Le client et le serveur exécutent cet algorithme en étape de verrouillage et le serveur ne traitera la commande commit que si la valeur transmise par le client correspond à ce que le serveur a calculé. De cette façon, le serveur ne validera jamais une transaction qui n'est pas exactement ce que le client a demandé.

5
Marc

Je n'ai pas assez de réputation pour ajouter un commentaire, mais j'ai trouvé que cette bibliothèque pouvait aider: https://github.com/amzn/ion-hash-js

Je suis ici:

const ionHashJS = require("ion-hash-js/dist/commonjs/es5/src/IonHash");
const ionStr =
  "INSERT INTO Vehicle { 'VIN': '12345', 'Type': 'Semi', 'Year': '2020', 'Make': 'Frank', 'Model': '313373', 'Color': 'Blue'  }";
const hashReader = ionHashJS.makeHashReader(
  ionJs.makeReader(ionStr),
  ionHashJS.cryptoIonHasherProvider("sha256")
);
hashReader.next();
hashReader.next();
const digest = hashReader.digest();
0
FroiD