cscalist

package
v1.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 28, 2024 License: MIT Imports: 16 Imported by: 0

README


layout: default title: x/cscalist

x/cscalist

Abstract

The module is designed to store and manage CSCA Master List. The list itself is provided by ICAO and contains root certificates of passport issuing authorities for a lot of countries. When obtained the passport signer's root certificate, you can check its presence in the Merkle tree, stored on Rarimo chain in a decentralized manner. Changing the list is possible via proposal.


Concepts

The CSCA certificates can only be obtained from the ICAO website in form of an LDIF file. The file is parsed by our LDIF SDK onto the hash values of raw public keys (Keccak256). The obtained hashes are used as leaves for the Merkle tree.

Dynamic treap-based Merkle tree is used to store the CSCA public key hashes, see treap. The reason is good consistency of treap with Cosmos KVStore, while updates of the list may be quite frequent. For each node the priority is deterministically derived from the key with formula: priority = keccak256(key) mod MAX_UINT64, where key is a hash of public key and MAX_UINT64 = 2^64-1.

In order to update the tree the proposal can be created. There are two types:

  • ReplaceCSCAListProposal - replaces the whole tree with a new one, very gas-consuming, suits for initial setup.
  • EditCSCAListProposal - add or remove certain CSCA public key hashes, flexible and efficient.

On update an operation CSCARootUpdate (see rarimocore module) is emitted in order to update the root key in external systems, e.g. EVM registration contract.

CLI is provided to work with LDIF (extract public keys, hash them or build a tree with root), query tree and module params, compare the current tree with the locally built from CSCA list.

Architecture

Implementation of the Merkle tree is copied from LDIF SDK and optimized for using with KVStore. Base methods are defined in x/cscalist/keeper/treap.go:

func (t Treap) Insert(ctx sdk.Context, key string) {}

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

func (t Treap) split(ctx sdk.Context, root, key string) (string, string) {}

func (t Treap) merge(ctx sdk.Context, left, rirght string) string {}

The Node structure is used to store the tree nodes. The public key hash received from proposal is processed in the following way:

  1. The hash must be a hex string with 0x prefix
  2. Hex string is set in new Node along with its Hash and ChildrenHash values.
  3. On node insertion, deeply in KVStore implementation, string is converted directly to bytes, like []byte(key).
  4. Some operations on treap are performed to build a new tree

Processing in 3 results in redundant gas consumption, because we could store bytes directly that are 2 times smaller than bytes of hex strings themselves. Also, algorithms of insertion and removal are not currently optimized for multiple values at once, resulting in a huge gas consumption.

State examples

Models can be found in proto/cscalist. Example values are provided in JSON for convenient reading.

Module params

{
  "params": {
    "rootKey": "0x36141b81b879c28068b3df0bbe9fad19c202b3ef7a140046e018c4153a8ce4c1",
    "rootUpdated": false,
    "updatedAtBlock": 854221,
    "lastUpdateOperationIndex": "0x2fd7af49f584db04cc8048fd09be7fccf01bd7efe6c93127c0dbae55e643d625"
  }
}

Node of the tree

{
  "node": {
    "key": "0x28815c9a1c9d638886d6ac193df55f98824c491d09bbbd712f96b5adfeba742e",
    "priority": 1833377742,
    "left": "0x",
    "right": "0x022e071cf4eed456dc7f3a36b7b190c6a1f991ef8c5809f612cb193e9c28af78",
    "hash": "0x2fd7af49f584db04cc8048fd09be7fccf01bd7efe6c93127c0dbae55e643d625",
    "childrenHash": "0x022e071cf4eed456dc7f3a36b7b190c6a1f991ef8c5809f612cb193e9c28af78"
  }
}

Replace CSCA list proposal

{
        "@type": "/rarimo.rarimocore.cscalist.ReplaceCSCAListProposal",
        "title": "Init",
        "description": "Lorem ipsum dolor sit amet concestetur!",
        "leaves": [
          "0x28815c9a1c9d638886d6ac193df55f98824c491d09bbbd712f96b5adfeba742e"
        ]
}

Edit CSCA list proposal

{
        "@type": "/rarimo.rarimocore.cscalist.EditCSCAListProposal",
        "title": "Add",
        "description": "Lorem ipsum dolor sit amet concestetur!",
        "toAdd": [
          "0x28815c9a1c9d638886d6ac193df55f98824c491d09bbbd712f96b5adfeba742e"
        ],
        "toRemove": []
}

Create proposal

You can create a draft proposal with rarimo-cored tx gov draft-proposal. Select other, then choose type cosmos.gov.v1.MsgExecLegacyContent. In messages[0].content section, fill @type (see proposals above) with module prefix rarimo.rarimocore.cscalist. Depending on the proposal type, fill either leaves or toAdd/toRemove fields with the list of CSCA public key hashes.

Or you can directly edit this sample (replace @type and leaves for another type):

{
  "messages": [
    {
      "@type": "/cosmos.gov.v1.MsgExecLegacyContent",
      "content": {
        "@type": "/rarimo.rarimocore.cscalist.ReplaceCSCAListProposal",
        "title": "Init",
        "description": "Lorem ipsum dolor sit amet concestetur!",
        "leaves": [
          "0x28815c9a1c9d638886d6ac193df55f98824c491d09bbbd712f96b5adfeba742e"
        ]
      },
      "authority": "rarimo10d07y265gmmuvt4z0w9aw880jnsr700jw44g3e"
    }
  ],
  "metadata": "ipfs://CID",
  "deposit": "10000000urmo"
}

When you have saved your proposal (assuming draft_proposal.json), you may submit it, make a deposit for it and vote, then retrieve your proposal. Here is the script sample for testing:

# approximate gas limit required to build full list of 382 nodes
rarimo-cored --keyring-backend test --home config/validator tx gov submit-proposal --gas 9999999999 --yes --from "<address>" "draft_proposal.json"
sleep 5
rarimo-cored --keyring-backend test --home config/validator tx gov deposit --gas 9999999 --yes --from "<address>" "<id>" 10000000stake
sleep 5
rarimo-cored --keyring-backend test --home config/validator tx gov vote --yes --gas 9999999 --from "<address>" "<id>" yes
sleep 5
rarimo-cored query gov proposal "<id>"

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExportGenesis

func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState

ExportGenesis returns the module's exported genesis

func InitGenesis

func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState)

InitGenesis initializes the module's state from a provided genesis state.

func NewProposalHandler

func NewProposalHandler(k keeper.Keeper) govv1beta1.Handler

Types

type AppModule

type AppModule struct {
	AppModuleBasic
	// contains filtered or unexported fields
}

AppModule implements the AppModule interface that defines the inter-dependent methods that modules need to implement

func NewAppModule

func NewAppModule(
	cdc codec.Codec,
	keeper keeper.Keeper,
) AppModule

func (AppModule) ConsensusVersion

func (AppModule) ConsensusVersion() uint64

ConsensusVersion is a sequence number for state-breaking change of the module. It should be incremented on each consensus-breaking change introduced by the module. To avoid wrong/empty versions, the initial version should be set to 1

func (AppModule) EndBlock

EndBlock contains the logic that is automatically triggered at the end of each block

func (AppModule) ExportGenesis

func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage

ExportGenesis returns the module's exported genesis state as raw JSON bytes.

func (AppModule) InitGenesis

func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate

InitGenesis performs the module's genesis initialization. It returns no validator updates.

func (AppModule) LegacyQuerierHandler deprecated

func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier

Deprecated: use RegisterServices

func (AppModule) QuerierRoute deprecated

func (AppModule) QuerierRoute() string

Deprecated: use RegisterServices

func (AppModule) RegisterInvariants

func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry)

RegisterInvariants registers the invariants of the module. If an invariant deviates from its predicted value, the InvariantRegistry triggers appropriate logic (most often the chain will be halted)

func (AppModule) RegisterServices

func (am AppModule) RegisterServices(cfg module.Configurator)

RegisterServices registers a gRPC query service to respond to the module-specific gRPC queries

func (AppModule) Route deprecated

func (am AppModule) Route() sdk.Route

Deprecated: use RegisterServices

type AppModuleBasic

type AppModuleBasic struct {
	// contains filtered or unexported fields
}

AppModuleBasic implements the AppModuleBasic interface that defines the independent methods a Cosmos SDK module needs to implement.

func NewAppModuleBasic

func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic

func (AppModuleBasic) DefaultGenesis

func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage

DefaultGenesis returns a default GenesisState for the module, marshalled to json.RawMessage. The default GenesisState need to be defined by the module developer and is primarily used for testing

func (AppModuleBasic) GetQueryCmd

func (AppModuleBasic) GetQueryCmd() *cobra.Command

GetQueryCmd returns the root query command for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module

func (AppModuleBasic) GetTxCmd

func (AppModuleBasic) GetTxCmd() *cobra.Command

GetTxCmd returns the root Tx command for the module. The subcommands of this root command are used by end-users to generate new transactions containing messages defined in the module

func (AppModuleBasic) Name

func (AppModuleBasic) Name() string

Name returns the name of the module as a string

func (AppModuleBasic) RegisterGRPCGatewayRoutes

func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux)

RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module

func (AppModuleBasic) RegisterInterfaces

func (AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry)

RegisterInterfaces registers a module's interface types and their concrete implementations as proto.Message

func (AppModuleBasic) RegisterLegacyAminoCodec

func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)

RegisterLegacyAminoCodec registers the amino codec for the module, which is used to marshal and unmarshal structs to/from []byte in order to persist them in the module's KVStore

func (AppModuleBasic) ValidateGenesis

func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error

ValidateGenesis used to validate the GenesisState, given in its json.RawMessage form

Directories

Path Synopsis
client
cli
Package types is a reverse proxy.
Package types is a reverse proxy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL