rarimo-core

x/identity

Abstract

The goal of identity module is to provide an aggregated information about Iden3 issuer states. It listens to deployed into Rarimo EVM StateV2 contract and collects the state transition events.


Concepts

Collected events’ information is recoded to the dynamic Merkle tree (based on treap data structure). The proof of concept for dynamic merkle tree is here: “https://github.com/olegfomenko/go-treap-merkle”.

To collect events identity module uses evm module hooks by defining the following method:

func (k Keeper) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error

It receives all emitted transaction logs in EVM module and filters them to process only StateTransited events.

After all state updates in the module EndBlock method the IDENTITY_AGGREGATED_TRANSFER operation will be created with current GIST and States root hash information. Also, the in all changed states lastUpdateOperationIndex will be updated.

Architecture

The basic methods of dynamic merkle to work with is defined in x/identity/keeper/treap.go:

func (t Treap) Split(ctx sdk.Context, root, key string) (string, string)

func (t Treap) Merge(ctx sdk.Context, r1, r2 string) string

func (t Treap) Remove(ctx sdk.Context, key string)

func (t Treap) Insert(ctx sdk.Context, key string, priority uint64)

and other...

That method are operating on the Node structure index.

Node index is based on corresponding StateInfo object hash (use CalculateHash()).

Also, every Node contains additional hash field that stores the HASH(self,HASH(left,right)).

Please refer to the corresponding hash(a, b string) string and updateNode(ctx sdk.Context, node *types.Node) to get more context about how we’re constructing merkle tree.

In the x/identity/keeper/keeper.go file we are defining the main entrypoints to interact with:


State

Params

Definition:

message Params {
  // Linear congruential generator params
  // https://en.wikipedia.org/wiki/Linear_congruential_generator
  uint64 lcgA = 1;
  uint64 lcgB = 2;
  uint64 lcgMod = 3;
  uint64 lcgValue = 4;
  // Address of identity state smart contract in rarimo chain
  string identityContractAddress = 5;
  string chainName = 6;
  string GISTHash = 7;
  uint64 GISTUpdatedTimestamp = 8;
  string treapRootKey = 9;
  repeated string statesWaitingForSign = 10;
}

Example:

{
  "params": {
    "lcgA": "1664525",
    "lcgB": "1013904223",
    "lcgMod": "4294967296",
    "lcgValue": "2900471886",
    "identityContractAddress": "0x753a8678c85d5fb70A97CFaE37c84CE2fD67EDE8",
    "chainName": "Rarimo",
    "GISTHash": "0x049f1325d5227edcefbca1dc4dc1b76dd981e54c874ec49ba964443086b49950",
    "GISTUpdatedTimestamp": "1691866982",
    "treapRootKey": "0x36141b81b879c28068b3df0bbe9fad19c202b3ef7a140046e018c4153a8ce4c1",
    "statesWaitingForSign": []
  }
}

Node

Definition:

message Node {
  // Node key (identity state hash)
  string key = 1;
  // Node priority (should be random)
  uint64 priority = 2;
  // Node left son key
  string left = 4;
  // Node right son key
  string right = 5;
  // Merkle hash. H = Hash(Hash(left_key|right_key)|self_key)
  string hash = 6;
  // Hash(left_key|right_key)
  string childrenHash = 7;
}

Example:

{
  "node": {
    "key": "0x36141b81b879c28068b3df0bbe9fad19c202b3ef7a140046e018c4153a8ce4c1",
    "priority": "4267815944",
    "left": "0x2d6a7c009097397071398f3b2a1855a5df9f6d9ce258846ba92de23aee0dfdf9",
    "right": "0x371e7f58b71fea562aa728619fed387134051e19a3efe0dac2c09557852c5a5c",
    "hash": "0x9cc3d207a5e341279f698cad512f517edb0e9d8df44181680f8d1d75b5573be2",
    "childrenHash": "0xeb2c9ef79b7415a7d38bd1497550084f6bf3ba2f871771b5030c8084b9ff51c8"
  }
}

StateInfo

Definition:

message StateInfo {
  // State info index (issuer id)
  string index = 1;
  // State hash in hex with 0x
  string hash = 2;
  // Creation timestamps
  uint64 createdAtTimestamp = 3;
  // Creation block (will not be used in state hash)
  uint64 createdAtBlock = 4;
  // Index of last update/create operation (will not be used in state hash)
  string lastUpdateOperationIndex = 5;
}

Example:

{
  "state": {
    "index": "0x106d23bb7bedce6caadddf7480ade7f2b8e93fa304fc51cc4030a66de90001",
    "hash": "0x22121ba37492dbb16203cd6dcdb446c4a5c56a4395b145b9403819bcf34141bf",
    "createdAtTimestamp": "1691866982",
    "createdAtBlock": "923813",
    "lastUpdateOperationIndex": "0x2fd7af49f584db04cc8048fd09be7fccf01bd7efe6c93127c0dbae55e643d625"
  }
}

Transactions

SetIdentityContractAddress

SetIdentityContractAddress - sets the Rarimo EVM StateV2 contract address. Can be called only once when the current address is 0x.

message MsgSetIdentityContractAddress {
  string creator = 1;
  string address = 2;
}