Journal contents in Amazon QLDB - Amazon Quantum Ledger Database (Amazon QLDB)

Journal contents in Amazon QLDB

In Amazon QLDB, the journal is the immutable transactional log that stores the complete and verifiable history of all the changes to your data. The journal is append-only and is composed of a sequenced and hash-chained set of blocks that contain your committed data and other system metadata. QLDB writes one or more chained blocks to the journal in a transaction.

This section provides an example of a journal block with sample data and describes the contents of a block.

Block example

A journal block contains transaction metadata along with entries that represent the document revisions that were committed in the transaction and the PartiQL statements that committed them.

The following is an example of a block with sample data.

Note

This block example is for informational purposes only. The hashes shown are not real calculated hash values.

{
  blockAddress:{
    strandId:"JdxjkR9bSYB5jMHWcI464T",
    sequenceNo:1234
  },
  transactionId:"D35qctdJRU1L1N2VhxbwSn",
  blockTimestamp:2019-10-25T17:20:21.009Z,
  blockHash:{{WYLOfZClk0lYWT3lUsSr0ONXh+Pw8MxxB+9zvTgSvlQ=}},
  entriesHash:{{xN9X96atkMvhvF3nEy6jMSVQzKjHJfz1H3bsNeg8GMA=}},
  previousBlockHash:{{IAfZ0h22ZjvcuHPSBCDy/6XNQTsqEmeY3GW0gBae8mg=}},
  entriesHashList:[
      {{F7rQIKCNn0vXVWPexilGfJn5+MCrtsSQqqVdlQxXpS4=}},
      {{C+L8gRhkzVcxt3qRJpw8w6hVEqA5A6ImGne+E7iHizo=}}
  ],
  transactionInfo:{
    statements:[
      {
        statement:"CREATE TABLE VehicleRegistration",
        startTime:2019-10-25T17:20:20.496Z,
        statementDigest:{{3jeSdejOgp6spJ8huZxDRUtp2fRXRqpOMtG43V0nXg8=}}
      },
      {
        statement:"CREATE INDEX ON VehicleRegistration (VIN)",
        startTime:2019-10-25T17:20:20.549Z,
        statementDigest:{{099D+5ZWDgA7r+aWeNUrWhc8ebBTXjgscq+mZ2dVibI=}}
      },
      {
        statement:"CREATE INDEX ON VehicleRegistration (LicensePlateNumber)",
        startTime:2019-10-25T17:20:20.560Z,
        statementDigest:{{B73tVJzVyVXicnH4n96NzU2L2JFY8e9Tjg895suWMew=}}
      },
      {
        statement:"INSERT INTO VehicleRegistration ?",
        startTime:2019-10-25T17:20:20.595Z,
        statementDigest:{{ggpon5qCXLo95K578YVhAD8ix0A0M5CcBx/W40Ey/Tk=}}
      }
    ],
    documents:{
      '8F0TPCmdNQ6JTRpiLj2TmW':{
        tableName:"VehicleRegistration",
        tableId:"BPxNiDQXCIB5l5F68KZoOz",
        statements:[3]
      }
    }
  },
  revisions:[
    {
      hash:{{FR1IWcWew0yw1TnRklo2YMF/qtwb7ohsu5FD8A4DSVg=}}
    },
    {
      blockAddress:{
        strandId:"JdxjkR9bSYB5jMHWcI464T",
        sequenceNo:1234
      },
      hash:{{t8Hj6/VC4SBitxnvBqJbOmrGytF2XAA/1c0AoSq2NQY=}},
      data:{
        VIN:"1N4AL11D75C109151",
        LicensePlateNumber:"LEWISR261LL",
        State:"WA",
        City:"Seattle",
        PendingPenaltyTicketAmount:90.25,
        ValidFromDate:2017-08-21,
        ValidToDate:2020-05-11,
        Owners:{
          PrimaryOwner:{
            PersonId:"GddsXfIYfDlKCEprOLOwYt"
          },
          SecondaryOwners:[]
        }
      },
      metadata:{
        id:"8F0TPCmdNQ6JTRpiLj2TmW",
        version:0,
        txTime:2019-10-25T17:20:20.618Z,
        txId:"D35qctdJRU1L1N2VhxbwSn"
      }
    }
  ]
}

In the revisions field, some revision objects might only contain a hash value and no other attributes. These are internal-only system revisions that don't contain user data. The hashes of these revisions are part of the journal's full hash chain, which is required for cryptographic verification.

Block contents

A journal block has the following fields:

blockAddress

The location of the block in the journal. An address is an Amazon Ion structure that has two fields: strandId and sequenceNo.

For example: {strandId:"BlFTjlSXze9BIh1KOszcE3",sequenceNo:14}

transactionId

The unique ID of the transaction that committed the block.

blockTimestamp

The timestamp when the block was committed to the journal.

blockHash

The 256-bit hash value that uniquely represents the block. This is the hash of the concatenation of entriesHash and previousBlockHash.

entriesHash

The hash that represents all of the entries within the block, including internal-only system entries. This is the root hash of the Merkle tree in which the leaf nodes consist of all the hashes in entriesHashList.

previousBlockHash

The hash of the previous chained block in the journal.

entriesHashList

The list of hashes that represent each entry within the block. This list includes the following entry hashes:

  • The Ion hash that represents transactionInfo. This value is calculated by hashing the entire transactionInfo Ion structure.

  • The root hash of the Merkle tree in which the leaf nodes consist of all the hashes in revisions.

  • Hashes that represent internal-only system metadata. These hashes might not exist in all blocks.

transactionInfo

An Amazon Ion structure that contains information about the statements in the transaction that committed the block. This structure has the following fields:

  • statements – The list of PartiQL statements and the startTime when they were executed. Each statement has a statementDigest hash, which is required to calculate the hash of the transactionInfo structure.

  • documents – The document IDs that were updated by the statements. Each document includes the tableName and tableId that it belongs to, and the index of the statement that updated it.

revisions

The list of document revisions that were committed in the block. Each revision structure contains all of the fields from the committed view of the revision.

This can also include hashes that represent internal-only system revisions that are part of the full hash chain of a journal.

Sample application

For a Java code example that validates a journal's hash chain using exported data, see the GitHub repository aws-samples/amazon-qldb-dmv-sample-java. This sample application includes the following class files:

  • ValidateQldbHashChain.java – Contains tutorial code that exports journal blocks from a ledger and uses the exported data to validate the hash chain between blocks.

  • JournalBlock.java – Contains a method named verifyBlockHash() that demonstrates how to calculate each individual hash component within a block. This method is called by the tutorial code in ValidateQldbHashChain.java.

For instructions on how to download and install this complete sample application, see Installing the Amazon QLDB Java sample application. Before you run the tutorial code, make sure that you follow Steps 1–3 in the Java tutorial to set up a sample ledger and load it with sample data.

See also

For more information about journals in QLDB, see the following topics: