syntax = "proto3";
package primitives;

// ASSET
// ================================================================================================

message Asset {
    // Asset represented as a word.
    primitives.Digest asset = 1;
}

// SMT (Sparse Merkle Tree)
// ================================================================================================

// Represents a single SMT leaf entry.
message SmtLeafEntry {
    // The key of the entry.
    Digest key = 1;

    // The value of the entry.
    Digest value = 2;
}

// Multiple leaf entries when hash collisions occur at the same leaf position.
message SmtLeafEntryList {
    // The list of entries at this leaf.
    repeated SmtLeafEntry entries = 1;
}

// A leaf in an SMT, sitting at depth 64. A leaf can contain 0, 1 or multiple leaf entries.
message SmtLeaf {
    oneof leaf {
        // An empty leaf index.
        uint64 empty_leaf_index = 1;

        // A single leaf entry.
        SmtLeafEntry single = 2;

        // Multiple leaf entries.
        SmtLeafEntryList multiple = 3;
    }
}

// The opening of a leaf in an SMT.
message SmtOpening {
    // The Merkle path to the leaf.
    SparseMerklePath path = 1;

    // The leaf itself.
    SmtLeaf leaf = 2;
}

// A different representation of a Merkle path designed for memory efficiency.
message SparseMerklePath {
    // A bitmask representing empty nodes.
    //
    // The set bit corresponds to the depth of an empty node. The least significant bit (bit 0)
    // describes depth 1 node (root's children). The `bit index + 1` is equal to node's depth.
    fixed64 empty_nodes_mask = 1;
    // The non-empty nodes, stored in depth-order, but not contiguous across depth.
    repeated Digest siblings = 2;
}

// MMR
// ================================================================================================

// Represents an MMR delta.
message MmrDelta {
    // The number of leaf nodes in the MMR.
    uint64 forest = 1;

    // New and changed MMR peaks.
    repeated Digest data = 2;
}

// MERKLE
// ================================================================================================

// Represents a Merkle path.
message MerklePath {
    // List of sibling node hashes, in order from the root to the leaf.
    repeated Digest siblings = 1;
}

// DIGEST
// ================================================================================================

// A hash digest, the result of a hash function.
message Digest {
    fixed64 d0 = 1;
    fixed64 d1 = 2;
    fixed64 d2 = 3;
    fixed64 d3 = 4;
}
