Как получить / вычислить CommitDigest при фиксации транзакции в AWS QLDB?

Я читал документы, пытаясь понять, как совершить транзакцию в QLDB, и для этого CommitDigest требуется, и в документации это описывается как:

Задает дайджест фиксации транзакции для фиксации. Для каждой активной транзакции должен быть передан дайджест фиксации. QLDB проверяет CommitDigest и отклоняет фиксацию с ошибкой, если дайджест, вычисленный на клиенте, не совпадает с дайджестом, вычисленным QLDB.

Итак, CommitDigest необходимо вычислить, но я не совсем уверен, что требуется для его вычисления, учитывая этот пример:

// ** 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();

Что мне нужно для хеширования CommitDigest в CommitTransaction вызов api?

2 ответа

Обновление: теперь доступен драйвер Node.js. Взгляните на https://github.com/awslabs/amazon-qldb-driver-nodejs/.

На момент написания драйвер QLDB Node.js все еще находится в разработке. Будет довольно сложно, если вы попытаетесь создать его самостоятельно, поэтому я бы предостерегал от этого. Тем не менее, я могу объяснить как цель, так и алгоритм CommitDigest.

Цель довольно проста: гарантировать, что транзакции фиксируются только в том случае, если сервер обработал точный набор операторов, отправленных клиентом (все по порядку, без дубликатов). HTTP - это запрос-ответ, поэтому запросы могут быть отброшены, обработаны не по порядку или дублированы. Драйверы QLDB правильно управляют обменом данными с QLDB, но наличие дайджеста фиксации в протоколе делает невозможным для реализации некорректно повторять запросы и при этом фиксировать транзакцию. Например, рассмотрите возможность увеличения баланса банка дважды, потому что HTTP-сообщение повторяется, даже если первый запрос был успешным.

Алгоритм также довольно прост: хеш-значение заполняется идентификатором транзакции, а затем обновляется с помощью оператора QLDB "точка". Каждое обновление "точки" в хэше оператора (sha256 строки PartiQL), а также IonHash всех значений привязки. Оператор точки - это способ, которым QLDB объединяет хеш-значения (это тот же оператор, который используется в API проверки.) и определяется как хэш конкатенации двух хешей, упорядоченный побайтным сравнением (со знаком, с прямым порядком байтов) между двумя хешами. Клиент и сервер запускают этот алгоритм в режиме блокировки, и сервер будет обрабатывать команду фиксации только в том случае, если значение, передаваемое клиентом, совпадает с вычисленным сервером. Таким образом, сервер никогда не совершит транзакцию, которая не совсем то, что запросил клиент.

У меня недостаточно репутации, чтобы добавить комментарий, но я обнаружил, что эта библиотека может помочь: https://github.com/amzn/ion-hash-js

Я сейчас здесь:

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();
Другие вопросы по тегам