Giter Club home page Giter Club logo

dymension's People

Contributors

anhductn2001 avatar artemijspavlovs avatar baibhavkumar1 avatar bert2002 avatar bodhi-crypo avatar cuithon avatar danwt avatar dependabot[bot] avatar dylanschultzie avatar faddat avatar fadeev avatar freshe4qa avatar gooddaisy avatar hardlydearly avatar hoangdv2429 avatar itaylevyofficial avatar itzhakbokris avatar liorzilp avatar luchenhan avatar mtsitrin avatar omritoptix avatar oxbau avatar pgoos avatar shaolin-flow avatar sigri44 avatar srene avatar trinitys7 avatar tropicaldog avatar victortrustydev avatar zale144 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dymension's Issues

Update rollapp state

Overview

When a sequencer is attached to a rollapp it can start to serve the rollapp chain and publish state updates. Create a UpdateState transaction.

Update State Message

Block description object:

  • height: is the height of the block.
  • stateRoot: is the state root of the block.
  • intermediateStatesRoot: is the root of a Merkle tree built from the ISRs of the block (Intermediate State Root).

The following fields are required for updating a state:

  • creator: is the bech32-encoded address of the sequencer account sent the transaction.
  • rollappId: is the rollapp that the sequencer belongs to and asking to update
  • startHigh: is the block height of the first block in the batch.
  • numBlocks: is the number of blocks included in this batch update.
  • DApath: is the description of the location on the DA layer.
  • version: is the version of the rollapp.
  • lastBD: the latest block descriptor of the last state update.
  • BDs: is a list of block description objects (one per block). the list must be ordered by height, start from startHeight to startHeight+numBlocks

State in store

StateInfo object:

  • sequencer: is the bech32-encoded address of the sequencer account sent the transaction.
  • rollappId: is the rollapp that the sequencer belongs to and asking to update
  • startHeight: is the block height of the first block in the batch.
  • numBlocks: is the number of blocks included in this batch update.
  • DApath: is the description of the location on the DA layer.
  • version: is the version of the rollapp.
  • BDs: is a list of block description objects (one per block). the list must be ordered by height, starting from startHeight to startHeight+numBlocks-1
  • additional:
  • creationHeight: is the height at which the UpdateState took place
  • status: is the status of the state update (see #49)

Validations

Basic validations

  1. blockDescriptors list size should be equal to numBlocks -> ErrInvalidNumBlocks
  2. blockDescriptors should contain all the high start from startHeight to (startHeight+numBlocks-1) in increasing order -> ErrInvalidBlockSequence
  3. blockDescriptors startHeight should be equal to lastBlockDescriptor.high+1

Stateful validation

  1. The rollapp exists -> ErrUnknownRollappId
  2. The sequencer is registered (can retrieve the rollapp object) -> ErrUnknownSequencer
  3. The rollappId is the rollappId that the sequencer belongs to -> ErrSequencerRollappMismatch
  4. Version is the currently active version of the rollapp -> ErrVersionMismatch
  5. If the rollapp has PermissionedAddress list, check that the sequencer is in list -> ErrLogic
  6. The StartHeight should be the latest+1 -> ErrWrongBlockHeight
  7. Only one update per rollapp is eligible in a block ->ErrMultiUpdateStateInBlock

Basic flow

Sending a transaction

  1. Sequencer can send a transaction for updating a batch
  2. If it is the first state update:
    • the lastBlockDescriptor.high should be zero
    • str&isrRoot are ignored
    • the start version is 0

Queries

  1. Retrieving the latest state update by rollapp

State finalization event

Overview

On EndBlocker() state updates that finished the dispute period are finalized.
We need to emit an event so light-clients (and relayer) could know when the state was finalized.

Event requirements

In order to support additional statuses of a state update, create a new event of StatusChange with the following attributes
RollappId - is the rollapp identifier
StartHeight - is the block height of the first block in the batch
NumBlocks - is the number of blocks included in this batch update
Status - is the status of the state update
StateInfoIndex - is an index for indexing to a specific state info

Emit event on state update

Overview

dymint sends UpdateState and checks that the state was actually updated.
The easiest and most efficient way to do it is to listen to an event when the state is updated on the chain.

Basic flow

On successful state update emit the following event:
message EventStateUpdate {
// rollappId is the rollapp that was updated
// The rollappId follows the same standard as cosmos chain_id
string rollappId = 1 [(gogoproto.moretags) = "yaml:"rollapp_id""];
// latestStateInfoIndex is a sequential increasing number, updating on each
// state update used for indexing to a specific state info
uint64 index = 2 [(gogoproto.moretags) = "yaml:"index""];
// startHeight is the block height of the first block in the batch
uint64 startHeight = 3 [(gogoproto.moretags) = "yaml:"start_height""];
// numBlocks is the number of blocks included in this batch update
uint64 numBlocks = 4 [(gogoproto.moretags) = "yaml:"num_blocks""];
// DAPath is the description of the location on the DA layer
string DAPath = 5 [(gogoproto.moretags) = "yaml:"DAPath""];
}

CreateSequencer test plan

Overview

CreateSequencer currently does nothing but create a sequencer object and provide quires.

Basic validation

  • Creator - legal bech32-encoded address of the sender
  • SequencerAddress - legal bech32-encoded address of the sender
  • Pubkey - is not legal or matches to SequencerAddress
  • RollappId - following the standard of cosmos chain_id
  • Description.Moniker - is not an empty string and follows length limitation
  • Description.*- follows length limitation

Good Path

  • Create N sequencers and attach them to M rollapps. After every single creation:
    • retrieve all
    • retrieve each created by sequencer address
    • retrieve all rollapps’ sequencer lists
    • retrieve each rollapps’ sequencer list by rollappId

Errors

  • SequencerAddress already exists

Create rollapp

Overview

In dYmension, a rollapp object contains all the configuration and definitions for a rollapp chain. Users can create a rollapp and later on add sequencers to serve it.

Create Rollapp Message

The following fields are required for creating a rollapp:

  • rollappId: is the unique identifier of the rollapp chain. The rollappId follows the same standard as cosmos chain_id.
  • creator: is the bech32-encoded address of the account sent the transaction (rollapp creator).
  • version: is the software and configuration version. starts from 1 and increases by one on every MsgUpdateState.
  • codeStamp: is a generated hash for unique identification of the rollapp code.
  • genesisPath: is the description of the genesis file location on the DA.
  • maxWithholdingBlocks: is the maximum number of blocks for an active sequencer to send a state update (MsgUpdateState).
  • maxSequencers: is the maximum number of sequencers allowed to serve to this rollapp.
  • permissionedAddresses: is a bech32-encoded address list of the sequencers that are allowed to serve this rollappId. In the case of an empty list, the rollapp is considered permissionless.

Basic flow

Sending a transaction

1. User can send a transaction for creating a new rollapp

Queries

 1. Retrieving a rollapp object by rollappId
 2. Retrieving a list of all rollapp objects

Rollapp deployers whitelist

Overview

Currently, we want to control who can deploy a rollapp. For the testnet, only the flagship rollapp will be deployed. Create a whitelist of the accounts that are allowed to deploy.

Business logic

On CreateRollapp, check that the sender is one of the accounts that are whitelisted. If the list is empty, everyone can create a rollapp.

Genesis

Create a module parameter for holding the list.

Create sequencer

Overview

A sequencer is like a full node serving a rollapp chain. A sequencer is attached only to one rollapp chain (rollappId) and identified by SequencerAddress. Contrary to a validator full nodes, the address that is used is a regular account address and not ValAddress nor ConsAddress. The sequencer must use its' SequencerAddress for interacting with dYmension.

Create Sequencer Message

Sequencer description object:

  • moniker: defines a human-readable name for the sequencer.
  • identity: defines an optional identity signature (ex. UPort or Keybase).
  • website: defines an optional website link.
  • security_contact: defines an optional email for security contact.
  • details: define other optional details.

The following fields are required for creating a sequencer:

  • sequencerAddress: is the bech32-encoded address of the sequencer account.
  • creator: is the bech32-encoded address of the account sent the transaction (sequencer creator)
  • pubKey: is the public key of the sequencer, as a Protobuf Any.
  • rollappId: defines the rollapp to which the sequencer belongs.
  • description: defines the descriptive terms for the sequencer.

Basic flow

Sending a transaction

1. User can send a transaction for creating a new sequencer

Queries

 1. Retrieving a list of all sequencers
 2. Retrieving a sequencer object by sequencerAddress
 3. Retrieving a list of all sequencers by rollappId

Validate rollapps' constrains in CreateSequencer

Overview

When creating a sequencer it is attached to a specific rollapp instance (identified by rollappID), and this rollapp should be already existing. A rollapp also has a limit of maximum sequencers that could be attached and might have a list of permissioned sequencers. Both needed to be checked when creating a new sequencer.

Basic flow

On CreateSequencer

1. Retrieve rollapp object from the rollapp keeper
    - if not exists return ErrUnknownRollappId
2. If PermissionedAddresses list isn't empty:
    - check if the sequencer is in the list, if not return ErrSequencerNotPermissioned
3. Check that number of rollapps attached to this rollapp does not exceed MaxSequencers:
    - if not(SequencersByRollapp(rollappId)<rollapp.MaxSequencers) return ErrMaxSequencersLimit

Tests

 1. ErrUnknownRollappId
 2. ErrSequencerNotPermissioned
 3. ErrMaxSequencersLimit

Validate active sequencer on UpdateState

Overview

Only the current active sequencer should be able to submit a state update.

Basic flow

CreateSequencer

  • On UpdateState, check if the sequencer sending the transaction is the active sequencer. On error -> ErrNotActiveSequencer

UpdateState test plan

Overview

After creating a rollapp and adding sequencers. The first sequencer becomes active, this active sequencer can start publishing state updates. Check the update-state transaction transition.

Basic validation

Check the basic validations as in Update rollapp state

Good Path

  1. Create M rollapps
  2. for each one, do:
    • Create N sequencers and attach them to a rollapp. After every single creation:
      • retrieve the active sequencer and check it was the first who added
    • Generate a block update with B blocks
    • Get the active sequencer and send a state update
      • retrieve the last state update and check it equal

Errors

  1. ErrSequencerUnauthorized:
    • Basic:
    • create rollapp
    • create an account
    • send update state from that account
    • When there are already sequencers:
    • create rollapp
    • create an account
    • create a sequencer
    • send update state from that account
  2. ErrWrongLastBlockDescriptor:
    • first update
    • setup
    • send update where the lastBlockDescriptor is not 0
    • wrong block high
    • setup
    • send update1 with N blocks
    • start a new block
    • send update2 where lastBlockDescriptor.high is not N
    • wrong block str
    • the same but wrong str
    • wrong block high
    • the same but wrong isrRoot
  3. ErrInvalidRollappVersion
    • first update
    • setup
    • send update where the version is not 0
    • during operation
    • setup
    • send the first update
    • start a new block
    • send additional update where the version is not 0
  4. ErrUpdateStateConflict
    • first update
    • setup
    • send the first update
    • send N additional updates (each should be rejected)
    • sduring operation
    • setup
    • send the first update
    • start a new block
    • send the second update
    • send N additional updates (each should be rejected)
    • skip block and update
    • setup
    • send the first update
    • start a new block
    • start a new block
    • send the second update
    • send N additional updates (each should be rejected)
  5. ErrLogic
    • create error logic
  6. ErrNotActiveSequencer
    • Basic:
    • create rollapp
    • create N sequencers
    • from each sequencer but the first one: send update state (which should be failed)

Seqeuencer is binded to rollapp

Once sequencer created for a specific rollapp, this sequencer address can't be registered or moved to different rollapp.

It enforce limitations on dev env,
as each time a new rollapp is initialized, it requires to use different settlement account and keyring.

I think at least for now, we should provide the possibiliy to either unregister sequencer, or to allow register same sequencer on different rollapps

Sequencer scheduler

Overview

A sequencer could be in many stages, among them: initialized and active. Initialized should be the initial status when the sequencer is created and active is when it is allowed to submit state updates. Currently, only one active sequencer will be supported and that is the first one that was attached to the rollapp.

State in store

Create a map between sequencerAddress and the sequencers' operating status.
Currently, a sequencers' operating status will have only two statuses: "PROPOSER" & "INACTIVE"

Basic flow

CreateSequencer

  • On sequencer creation, check if it's the first rollapps' sequencer, if it is, set it to PROPOSER, otherwise to INACTIVE

Queries

  • Retrieve sequencers' operating status by their' address

setup_local.sh should allow to overwrite dymd executable

The setup_local.sh doesn't build and overwrite the dymd executable.

It means that if we built dymd once on version X,
and now we change the branch to version Y,
the setup_local.sh as used in the docs will not build the new version

CreateRollapp test plan

Overview

CreateRollapp currently does nothing but create a rollapp object and provide quires.

Basic validation

  • Creator - legal bech32-encoded address of the sender
  • RollappId - following the standard of cosmos chain_id
  • MaxSequencers - must be greater than zero
  • MaxWithholdingBlocks - must be greater than zero
  • PermissionedAddresses - (1) legal bech32-encoded address (2) no duplications in the list

Good Path

  • Create N rollapps from M creators, each with Y PermissionedAddresses. After every single creation:
    • retrieve all
    • retrieve each created by rollappId

Errors

  • ErrRollappExists
  • ErrInvalidwMaxSequencers
  • ErrInvalidwMaxWithholding
  • ErrInvalidPermissionedAddress
  • ErrPermissionedAddressesDuplicate

Limit the amount of RollApps an address may deploy

Overview

In a permissioned deployment of RollApps, we are limiting the amount of RollApps are deployed not only the addresses that may deploy a RollApp. For example, one address should only be able to deploy one RollApp.

The example for this is that it hard codes a limit for RollApp deployment based on on-chain governance reducing the trust-assumption that an address will only deploy one RollApp.

Task

In the SetRollapp function, we should check that the address key has zero RollApp IDs. If it has more than zero than a RollApp has already been deployed.

func (k Keeper) SetRollapp(ctx sdk.Context, rollapp types.Rollapp)

Integration: change state fields of BlockDescriptor to be byte array

BlockDescriptor holds two states: StateRoot & IntermediateStatesRoot. Currently, they are strings that are not compatible with dymint. change it to byte array. The array size must be 32 bytes.
Add a check of the array size in UpdateStates' ValidateBasic and update tests as well.

Sequencer Dymint PubKey

Overview

Currently, the sequencers' PubKey is the public key of the sequencers' account on the hub.
The key is provided on MsgCreateSequencer and stored as part of the sequencer.

Change

The PubKey should be the public key of the dymint client that the sequencer is running.
The public key prototype should be tendermint/crypto/keys.proto

Rename DymintPubKey

To make it more clear, use DymintPubKey as the field name and not PubKey

Normalize queries

Overview

Queries should follow the following standard:

  • Keep minimum queries (i.e List and Get)
  • Query by filters when possible [instead of creating an endpoint for each filter]

Changes

get-state-info-by-height [rollapp-id] [height]

Merge with show-rollapp-state-info [rollapp-id] [state-index] by adding flags

latest-finalized-state-info [rollapp-id]

change to show-latest-finalized-state-info

IRC client callbacks

Overview

The IRC is like IBC for rollapps; therefore IRC utilizes the IBC stack using dymint-light-client.
The dymint-light-client doesn't check the validity of the consensus as there is no consensus for rollapps.

Checking validity

The dymension hub is maintaining the rollapp state and finalization. Following ADR-01, a rollapp client state should be updated only when the state is finalized.
Using IBC client-callback allows for validating any client state changes in the application logic.

Client callbacks

In each callback, check that the state as reported in the transaction is a finalized state as the settlement layer knows.
If the state is not finalized, return error: ErrNotFinalizedState

Testing

Use IBC testing for creating a chain identified as a dymint and another chain as the hub.
Check 02-transactions for finalized state and not-finalized state.

Rollapp states' status

Overview

In dYmension protocol, a state update could be in some statuses. Currently, fraud-proofs are not supported, therefore only the following statuses are supported:
Received - transaction was published on dYmension chain
Finalized - the “Dispute Period” has ended and this state is considered final

Business logic

Create a status object to provide a state and transition functions:

  • Received -> Finalized

Genesis

Create module parameters for DisputeBlockPeriod.

Query latest finalized StateInfo

Overview

The states of a rollapp are indexed internally by the number of UpdateState transactions.
But there is no easy way to query the latest StateInfo that was finalized.

Query

Create a new query: LatestFinalizedStateInfo to retrieve this information by rollappId

Refactor of StateIndex

StateIndex is used in 3 places:

  1. As a pointer to the latest state of a rollapp (StateInfo)
  2. As a key for the rollapps' states (StateInfo)
  3. As a value of the finalization queue (see Finalize rollapp state)

The way it is currently used is confusing. The name should tell that it is related to a StateInfo and the usage as a pointer to the latest state should be implied by the store name.

  • Rename StateInfo structure to StateInfoIndex and move it to the same proto
  • Rename the StateIndex store to LatestStateInfoIndex
  • Rename files of state_index that are related to LatestStateInfoIndex to latest_state_info_index

Query StateInfo by rollapp height

Overview

Per rollapp, the settlement stores and index block-batch updates by what is called StateInfoIndex.
In that way, the updates are indexed by time (the first update at index 1 and so on),
The settlement tracks the last index, but not giving an easy and efficient way to query 'StateInfo' based on rollapp block height.

Usage

In the ibc_client_hooks there is a validation process that requires obtaining the 'StateInfo' by rollapp height. Currently, it is done in 'getStateInfo' method which is implemented in the hooks. The logic that is applied there today is inefficient and makes scanning over all the indexes (from the newest to oldest).

Changes

We need to make a public query so other clients could access state information by rollapp high.
The algorithm/indexing for retrieving a StateInfo by rollapp height should be efficient.

Algorithm

The following algorithm is searching for the block batch of height 'h'

  1. start_batch_index := 1
  2. end_batch_index := latest
  3. start_height := block_batch[end_batch_index ].StartHeight
  4. end_height := block_batch[end_batch_index ].EndHeight
    // calculate the average blocks per batch
  5. avg := (end_height - start_height)/(end_batch_index-start_batch_index)
    // check the candidate block batch
  6. candidate_batch_index := (h-start_height)/avg
    // check the candidate
  7. if (block_batch[candidate_batch_index].StartHeight > h)
    7.1 start_batch_index := candidate_batch_index
  8. else
    8.1 if (block_batch[candidate_batch_index].EndHeight < h)
    8.1.1 end_batch_index := candidate_batch_index
    8.2 else
    8.2.2 return end_batch_index
  9. goto (3)

Set a genesis parameter for permissionless RollApp deployment

Overview

Eventually there will be multiple testnets (i.e. permissioned RollApp deployment and permissionless). They will live in parallel to let developers to build on the permissionless testnet and prepare a permissioned for launch which will upgrade to a permissionless network.

Proposal

Recommend setting a genesis parameter that indicates if the network is permissioned and who are the administrators. Setting this parameter to false remove admins and removes permissioned constraints.

Refactor for shared types and methods

Overview

Sometimes we need shared definitions and functions that more than one module uses. For example, the message Sequencers is a list of sequencers' addresses. This type is used both by the rollapp and the sequencer module.

Requirements

  1. Create a shared package for holding shared code
  2. Move the message Sequencers proto to share

Rollapp state finalization

Overview

Following the verified optimism protocol, the status of a state should change. Currently, the supported status changes are as described here.

State

Hold a map from FinalizationHeight to FinalizationQueue which indicates what stateInfo should be finalized on FinalizationHeight.

Basic Flow

On Update State

add the StateIndex to the map where the FinalizationHeight is current blockHeight+DisputePeriodInBlocks

On End Block

check if there are states to finalize and change the status them to finalize

The SL return sometimes: "only one state update can take place per block" even if the next updated occurs for new block

In the UpdateState method the current block height is compared to the one stored in the last state and if they are equal, an error is returned.
the issue is that when it running on simulation mode, the handled block is the previous one so the block-heights-validation is wrong here.
the solution is to remove the block-height validation if the UpdateState method not running in delivery mode.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.