Receipt - zoobc/zoobc-core GitHub Wiki

Receipt is an object that act as a proof that nodes communicated. It is received by the sender (of data, ex: block, transaction, etc) and generated by the receiver of the data.

Receipt Structure

No Field Type Description
1 SenderPublicKey []byte The data sender (block/transaction sender)
2 RecipientPublicKey []byte The data receiver who validate the data it received, and generate the receipt for it
3 DataType uint32 The type of the data broadcasted by the sender, for now there are [transaction, block]
4 DataHash []byte The hash of the data sent by the sender
5 ReferenceBlockHash []byte The recipient latest block's hash
6 ReferenceBlockHeight uint32 The recipient latest block's height
7 ReceiptMerkleRoot []byte The latest Receipt Merkle Root if the recipient
8 RecipientSignature []byte The signature of the [SenderPublicKey, RecipientPublicKey, ReferenceBlockHeight, ReferenceBlockHash, DataType, DataHash, ReceiptMerkleRoot] written in order

Receipt Types

There are two types of receipt:

  • Linked Receipt

    Linked receipt have total 2 value of score.

  • un-linked Receipt

    Un-linked receipt have total 0.5 value of score

A receipt is linked when it can prove a receipt with rmr_linked value equal to its merkle root value has already been published.

Receipt Collection

Node broadcast data (block, transaction) to collect receipts.

Storing Receipt

Sender Node will need to store the received receipts in a chunk of n number of receipts in memory, and store to database afterward:

  • Collect receipt in memory for size of n. (n should be the power of 2)
  • Build merkle tree and its root once have reach n number of receipt.
  • Store the tree and the root in receipt_merkle table, and all receipts will be stored in node_receipt table with their respective order in the merkle tree.

Data Structure

To store the receipts, we'll have three tables:

node_receipt, to store node's individual receipt (this will be different across different node)

No db name proto name db type proto type
1 sender_public_key SenderPublicKey BLOB []byte
2 recipient_public_key RecipientPublicKey BLOB []byte
3 data_type DataType INTEGER uint32
4 data_hash DataHash BLOB []byte
5 reference_block_height ReferenceBlockHeight INTEGER uint32
6 reference_block_hash ReferenceBlockHash BLOB []byte
7 receipt_merkle_root ReceiptMerkleRoot BLOB []byte
8 recipient_signature RecipientSignature BLOB []byte
9 rmr_index RMRIndex INTEGER uint32

merkle_root, to store the merkle root and its tree of the collected receipt, this value will also be used to be included in the receipt generated by the owner. (this table will also be unique across different node)

node_batch_receipt, to store the receipt temporarily before building the merkle root and store the receipt in the node_receipt table, (*we are considering putting this in a kv db)

No db name proto name db type proto type
1 sender_public_key SenderPublicKey BLOB []byte
2 recipient_public_key RecipientPublicKey BLOB []byte
3 data_type DataType INTEGER uint32
4 data_hash DataHash BLOB []byte
5 reference_block_height ReferenceBlockHeight INTEGER uint32
6 reference_block_hash ReferenceBlockHash BLOB []byte
7 receipt_merkle_root ReceiptMerkleRoot BLOB []byte
8 recipient_signature RecipientSignature BLOB []byte

network_receipt, to store the receipts published in a block, this table should be identical across different nodes.

Publish Receipt

Node that want to include their receipt in the block they want to publish will need to:

  • Pay attention to the block that may have included one of its own merkle root, this will be later used to filter the receipt to be included in a block.

  • node will prioritize receipt that can be linked to broadcasted block rmr (receipt merkle root)

  • on linked receipt, node will need to provide the list of hashes needed to proof the validity of the receipt, by:

    • get the merkle tree from receipt_merkle table.
    • get the least needed number of hashes to proof the validity of the receipt chosen.
  • if there isn't enough linked receipt to provide, node will pick the un-linked receipt (the opposite of linked receipt) to the list.

Published Receipt Validation

  • if linked, validate the receipt and its intermediate hashes against its merkle root

  • if unlinked, give the unlinked score

  • if all the receipt in the block is valid and good to go, store them in published_receipt table so that we can link the future receipts to see if the rmr has been published before.